// work form char *
int ipbatch(const char *arg) 
{
   int rval = 0;
   if(!strcmp(arg,"commit")) {
      rval = ipbatch(mybatch);
      mybatch.clear();
   }
   else 
      mybatch.push_back(std::string(arg));
   return rval;
}
// or from single strings
int ipbatch(const std::string &arg) 
{
   int rval = 0;
   if(arg == "commit") 
   {
      rval = ipbatch(mybatch);
      mybatch.clear();
   }
   else 
      mybatch.push_back(arg);
   return rval;
}
Example #3
0
int stop_guardian(std::vector<std::string> & parameters, std::string & response)
{
	int error = 0;
	std::vector<std::string>ipb;	
	response = "Guardian Process Terminated";

	killunknownprocess("guardian.pl");

	ipbatch(ipb);
		
	return 0;
}
Example #4
0
int set_ipblock(std::vector<std::string> & parameters, std::string & response)
{
	int error = 0;
	ConfigCSV config("/var/smoothwall/ipblock/config");
	std::vector<std::string>ipb;
	std::string::size_type n;
	
	ipb.push_back("iptables  -F ipblock");
	for (int line = config.first(); line == 0; line = config.next())
	{
		const std::string & remip = config[0];
		const std::string & log = config[1];
		const std::string & target = config[2];
		const std::string & enabled = config[3];

		// are we complete?
		if (remip == "" && enabled != "")
			break;

		if ((n = remip.find_first_not_of(IP_NUMBERS)) != std::string::npos)
		{
			response = "Bad remote IP: " + remip;
			error = 1;
			goto EXIT;
		}
		if (!(target == "DROP" || target == "REJECT"))
		{
			response = "Bad target: " + target;
			error = 1;
			goto EXIT;
		}
		if (enabled == "on")
		{
			if (log == "on")
				ipb.push_back("iptables -A ipblock -s " + remip + " -j LOG --log-prefix \"Denied-by-filter:ipblock \"");
			ipb.push_back("iptables -A ipblock -s " + remip + " -j " + target);
		}
	}

	error = ipbatch(ipb);
	
	if (error)
	{
		response = "ipbatch failure";
		goto EXIT;
	}
	
	response = "Block rules set";

EXIT:
	return error;
}
Example #5
0
int start_guardian(std::vector<std::string> & parameters, std::string & response)
{

	int error = 0;
	std::vector<std::string>ipb;
	ConfigVAR settings("/var/smoothwall/snort/settings");

	if (settings["ENABLE_GUARD"] == "on")
	{
		response = "Guardian Process started";

		error = simplesecuresysteml("/usr/local/sbin/guardian.pl", NULL, NULL);
	
		error = ipbatch(ipb);

		if (error)
			response = "Guardian Start Failed!";
		else
			response = "Guardian Start Successful";
	}
	return error;
}
Example #6
0
int set_timed_access(std::vector<std::string> & parameters, std::string & response)
{
	int error = 0, preStartTime, postStopTime;
	ConfigVAR settings("/var/smoothwall/timedaccess/settings");
	ConfigCSV config("/var/smoothwall/timedaccess/machines");
	std::vector<std::string>ipb;
	std::string::size_type n;
	std::string daysOfWeek = "";
	std::ostringstream ssPreStartHour, ssPreStartMin, ssPostStopHour, ssPostStopMin;

	// Convert the times to decimal; a day has 1440 minutes (0-1439).
	preStartTime = (strtol (settings["START_HOUR"].c_str(), NULL, 10)*60 +
		strtol (settings["START_MIN"].c_str(), NULL, 10)) - 1;
	postStopTime = (strtol (settings["END_HOUR"].c_str(), NULL, 10)*60 +
		strtol (settings["END_MIN"].c_str(), NULL, 10)) + 1;
	// preStartTime and postStopTime are used as end and start times, respectively,
	// when the start time>00:00 and/or the end time<23:59:59.
	ssPreStartHour << preStartTime/60;
	ssPreStartMin << preStartTime%60;
	ssPostStopHour << postStopTime/60;
	ssPostStopMin << postStopTime%60;

	
	// Send 'em to John
	ipb.push_back("iptables -F timedaccess\n");

	// If enabled, generate the rules
	if (settings["ENABLE"] == "on")
	{
		// Days of the week the rule applies
		if (settings["DAY_0"]  == "on") daysOfWeek += ",Mon";
		if (settings["DAY_1"]  == "on") daysOfWeek += ",Tue";
		if (settings["DAY_2"]  == "on") daysOfWeek += ",Wed";
		if (settings["DAY_3"]  == "on") daysOfWeek += ",Thu";
		if (settings["DAY_4"]  == "on") daysOfWeek += ",Fri";
		if (settings["DAY_5"]  == "on") daysOfWeek += ",Sat";
		if (settings["DAY_6"]  == "on") daysOfWeek += ",Sun";
		if (daysOfWeek.length() > 0)
		{
			daysOfWeek[0] = ' ';
			daysOfWeek = " --weekdays" + daysOfWeek;
		}

		// For each IP, generate the rules
		for (int line = config.first(); line == 0; line = config.next())
		{
			const std::string &ip = config[0];
			
			if ((n = ip.find_first_not_of(IP_NUMBERS)) != std::string::npos) 
			{
				// illegal characters
				response = "Bad IP: " + ip;
				error = 1;
				return error;
			}

			if (settings["MODE"] == "ALLOW")
			{

				// Allowing

				if (preStartTime >= 0)
				{
					// There is time before the start time
					ipb.push_back("iptables -A timedaccess -s " + ip + " -m time" +
						" --kerneltz" +
						" --timestart 00:00:00" +
						" --timestop " + ssPreStartHour.str() + ":" + ssPreStartMin.str() + ":59" +
						daysOfWeek + " -j timedaction");
					ipb.push_back("iptables -A timedaccess -d " + ip + " -m time" +
						" --kerneltz" +
						" --timestart 00:00:00" +
						" --timestop " + ssPreStartHour.str() + ":" + ssPreStartMin.str() + ":59" +
						daysOfWeek + " -j timedaction");
				}

				// The time interval
				ipb.push_back("iptables -A timedaccess -s " + ip + " -m time" +
					" --kerneltz" +
					" --timestart " + settings["START_HOUR"] + ":" + settings["START_MIN"] + ":00" +
					" --timestop " + settings["END_HOUR"] + ":" + settings["END_MIN"] + ":59" +
					daysOfWeek + " -j RETURN");
				ipb.push_back("iptables -A timedaccess -d " + ip + " -m time" +
					" --kerneltz" +
					" --timestart " + settings["START_HOUR"] + ":" + settings["START_MIN"] + ":00" +
					" --timestop " + settings["END_HOUR"] + ":" + settings["END_MIN"] + ":59" +
					daysOfWeek + " -j RETURN");

				if (postStopTime <= 1439)
				{
					// There is time after the stop time
					ipb.push_back("iptables -A timedaccess -s " + ip + " -m time" +
						" --kerneltz" +
						" --timestart " + ssPostStopHour.str() + ":" + ssPostStopMin.str() + ":00" +
						" --timestop 23:59:59" +
						daysOfWeek + " -j timedaction");
					ipb.push_back("iptables -A timedaccess -d " + ip + " -m time" +
						" --kerneltz" +
						" --timestart " + ssPostStopHour.str() + ":" + ssPostStopMin.str() + ":00" +
						" --timestop 23:59:59" +
						daysOfWeek + " -j timedaction");
				}
			} else {

				// Rejecting

				if (preStartTime >= 0)
				{
					// There is time before the start time
					ipb.push_back("iptables -A timedaccess -s " + ip + " -m time" +
						" --kerneltz" +
						" --timestart 00:00:00" +
						" --timestop " + ssPreStartHour.str() + ":" + ssPreStartMin.str() + ":59" +
						daysOfWeek + " -j RETURN");
					ipb.push_back("iptables -A timedaccess -d " + ip + " -m time" +
						" --kerneltz" +
						" --timestart 00:00:00" +
						" --timestop " + ssPreStartHour.str() + ":" + ssPreStartMin.str() + ":59" +
						daysOfWeek + " -j RETURN");
				}

				// The time interval
				ipb.push_back("iptables -A timedaccess -s " + ip + " -m time" +
					" --kerneltz" +
					" --timestart " + settings["START_HOUR"] + ":" + settings["START_MIN"] + ":00" +
					" --timestop " + settings["END_HOUR"] + ":" + settings["END_MIN"] + ":59" +
					daysOfWeek + " -j timedaction");
				ipb.push_back("iptables -A timedaccess -d " + ip + " -m time" +
					" --kerneltz" +
					" --timestart " + settings["START_HOUR"] + ":" + settings["START_MIN"] + ":00" +
					" --timestop " + settings["END_HOUR"] + ":" + settings["END_MIN"] + ":59" +
					daysOfWeek + " -j timedaction");

				if (postStopTime <= 1439)
				{
					// There is time after the stop time
					ipb.push_back("iptables -A timedaccess -s " + ip + " -m time" +
						" --kerneltz" +
						" --timestart " + ssPostStopHour.str() + ":" + ssPostStopMin.str() + ":00" +
						" --timestop 23:59:59" +
						daysOfWeek + " -j RETURN");
					ipb.push_back("iptables -A timedaccess -d " + ip + " -m time" +
						" --kerneltz" +
						" --timestart " + ssPostStopHour.str() + ":" + ssPostStopMin.str() + ":00" +
						" --timestop 23:59:59" +
						daysOfWeek + " -j RETURN");
				}
			}
		}
	}
	
	error = ipbatch(ipb);
	if (error) response = "ipbatch failure when setting chain timedaccess";
	else response = "timed access set";

	return error;
}
//#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@>
int set_portfw(std::vector<std::string> & parameters, std::string & response)
{
 int error = 0;
 std::string::size_type n;
 std::string::size_type p;
 std::vector<std::string>ipb;

 std::string localipfile = "/var/smoothwall/red/local-ipaddress";
 std::string ifacefile = "/var/smoothwall/red/iface";
 std::string cmdprefix = "/var/smoothwall";
 std::string configfile = cmdprefix + "/portfw/config";
 std::string aliasfile = cmdprefix + "/portfw/aliases";
 std::string sncheckfile = cmdprefix + "/portfw/subcheck";
 ConfigSTR   localip(localipfile);
 ConfigSTR   red_iface(ifacefile);
 ConfigCSV   fwdconf(configfile);
 ConfigCSV   aliases(aliasfile);
 ConfigVAR   subnetcheck(sncheckfile);

 std::string greencheck  = subnetcheck["GREEN"];
 std::string purplecheck = subnetcheck["PURPLE"];
 std::string orangecheck = subnetcheck["ORANGE"];

 // preset the response to a success, changed only on error, always return zero

 response = "Port forwarding rules set";

 if (localip.str() == "")
 {
  response = "Abort, could not open red local IP file (" + localipfile + ")";
  return errrpt (response);
 }
 if (localip.str().find_first_not_of(IP_NUMBERS) != std::string::npos)
 {
  response = "Abort, bad local IP: " + localip.str();
  return errrpt (response);
 }
 if (red_iface.str() == "")
 {
  response = "Abort, could not open red interface file (" + ifacefile + ")";
  return errrpt (response);
 }
 if (red_iface.str().find_first_not_of(INTERFACE) != std::string::npos)
 {
  response = "Abort, bad red interface specifier: " + red_iface.str();
  return errrpt (response);
 }
 std::string red_if      = red_iface.str();
 std::string fwdest_out  = "";
 std::string dest_out    = "";
 std::string ifc_in_out  = "";
 std::string ifc_out_out = "";
 std::string fwdportdest = "";
 std::string srcipmac_out= "";
 std::string dport_out   = "";
 std::string fwdport_out = "";
 std::string prot_out    = "";
 std::string dnat_out    = "";
 std::string tgt_out     = "";
 std::string in_dest     = "";
 bool bounce_type        = false;
 bool forwarding         = false;
 bool translating        = false;
 bool negated_source     = false;
 std::string temp_source = "";
 std::string internal_if = "";
 std::string conn_green  = "0xD0000000";
 std::string conn_purple = "0xE0000000";
 std::string conn_orange = "0xF0000000";
 std::string green_if    = "";
 std::string green_ifip  = "";
 std::string orange_if   = "";
 std::string orange_ifip = "";
 std::string purple_if   = "";
 std::string purple_ifip = "";
 /*
 The mark_mask value can only be used if we switch to CONNMARK tracking
 std::string mark_mask   = "0xFFF00000/";
 //=============================================================================>
 // We use the upper three nybbles of the available CMARK sequence numbers for
 // identifying the CMARKs associated with Full Firewall Control.  Any other
 // applications using CMARKs must be aware of this, always using a CMARK mask
 // that is not greater than 0x000FFFFF.  Available only if we use CONNMARK
 //=============================================================================>
 */
 rmdupes (ipb, "iptables -t filter -F portfwf");  // filtering rules  (moved stk)
 rmdupes (ipb, "iptables -t nat -F portfw");      // DNAT forwarding        (stk)
 rmdupes (ipb, "iptables -t mangle -F portfwb");  // MARK bounce & OMask    (stk)
 rmdupes (ipb, "iptables -t nat -F portfw_post"); // SNAT bounce & OMask    (add)
 rmdupes (ipb, "iptables -t filter -F portfwi");  // filter rules for INPUT (add)
 rmdupes (ipb, "iptables -t filter -F subnetchk");// filter rules FOR/INPUT (add)

 // ============================================================================>
 // we allow masking outbound to a red alias by having an association in
 // the alias file between a single internal IP and the alias interface
 // ============================================================================>
 // Here we find the internal interfaces for possible bouncing and create the
 // rules for masking outbounds to alias interfaces as we read the alias file

 unsigned int mark_seq = 0x800;

 for (int line = aliases.first(); line == 0; line = aliases.next())
 {
  char conn_mark[15] = "";

  const std::string & f_ifcolor   = aliases[0];
  const std::string & f_ifalias   = aliases[1];
  const std::string & f_realif    = aliases[2];
  const std::string & f_ipaddress = aliases[3];
  const std::string & f_addmask   = aliases[4];
  const std::string & f_enabled   = aliases[7];
  const std::string & f_mask2add  = aliases[9];
  std::string scprefixf = "iptables -t filter -A";
  std::string sclogpre = " -j LOG --log-prefix ..FFC..not.";
  std::string sclogpost = ".subnet..";
  std::string sclogrej = " -j REJECT";

  //  Allow DHCP to bypass subnet checking
  rmdupes (ipb, scprefixf + " subnetchk -p udp --dport 67 -j RETURN");
  rmdupes (ipb, scprefixf + " portfwi -j subnetchk");
  rmdupes (ipb, scprefixf + " portfwf -j subnetchk");

  //============================================================================>
  //  log and reject any packets with a source that is not in the correct
  //  subnet for the interface that received them
  //===>>  To disable:  set "(GREEN|PURPLE|ORANGE)=off" in the "sncheckfile"

  if (f_ifcolor == "GREEN")
  {
   green_if = f_realif;
   green_ifip = f_ipaddress;
   if (greencheck != "off")
   {
    char cidr[5] = "";
    sprintf((char*) cidr, "/%d", snet2cidr(f_addmask));

    std::string scpostfixl = (" -i " + green_if + " ! -s " + green_ifip + cidr +
     sclogpre + f_ifcolor + sclogpost);
    std::string scpostfixr = (" -i " + green_if + " ! -s " + green_ifip + cidr +
     sclogrej);

    rmdupes (ipb, scprefixf + " subnetchk" + scpostfixl);
    rmdupes (ipb, scprefixf + " subnetchk" + scpostfixr);
   }
  }
  if (f_ifcolor == "ORANGE")
  {
   orange_if = f_realif;
   orange_ifip = f_ipaddress;
   if (orangecheck != "off")
   {
    char cidr[5] = "";
    sprintf((char*) cidr, "/%d", snet2cidr(f_addmask));

    std::string scpostfixl = (" -i " + orange_if + " ! -s " + orange_ifip + cidr +
     sclogpre + f_ifcolor + sclogpost);
    std::string scpostfixr = (" -i " + orange_if + " ! -s " + orange_ifip + cidr +
     sclogrej);

    rmdupes (ipb, scprefixf + " subnetchk" + scpostfixl);
    rmdupes (ipb, scprefixf + " subnetchk" + scpostfixr);
   }
  }
  if (f_ifcolor == "PURPLE")
  {
   purple_if = f_realif;
   purple_ifip = f_ipaddress;
   if (purplecheck != "off")
   {
    char cidr[5] = "";
    sprintf((char*) cidr, "/%d", snet2cidr(f_addmask));

    std::string scpostfixl = (" -i " + purple_if + " ! -s " + purple_ifip + cidr +
     sclogpre + f_ifcolor + sclogpost);
    std::string scpostfixr = (" -i " + purple_if + " ! -s " + purple_ifip + cidr +
     sclogrej);

    rmdupes (ipb, scprefixf + " subnetchk" + scpostfixl);
    rmdupes (ipb, scprefixf + " subnetchk" + scpostfixr);
   }
  }
  if (f_mask2add != "" && f_mask2add.find_first_of("/") == std::string::npos &&
   f_ifalias.find_first_of(":") != std::string::npos && f_enabled == "on")

  //============================================================================>
  // Make sure we have an alias interface and a single IP to mask
  {
   sprintf((char*) conn_mark, "%#010x", (++mark_seq) * 0x100000);
   conn_mark[10] = 0;

   rmdupes (ipb, "iptables -t mangle -A portfwb -s " + f_mask2add +
    " -j MARK --set-mark " + conn_mark);

   rmdupes (ipb, "iptables -t nat -A portfw_post -o " + red_if + " -s " + f_mask2add +
    " -m mark --mark " + conn_mark + " -j SNAT --to-source " + f_ipaddress);
  }
  if (mark_seq > 0x8FF)
  {
   response = "Abort, more than 255 aliases not supported, reduce alias count.";
   return errrpt (response);
  }
  if (error)
  {
   response = "Abort in alias file for " + f_ifalias + " interface.";
   return errrpt (response);
  }
 }//     <<== End of reading "aliasfile"

 //=============================================================================>
 // This is to clean up any previously entered jumps around the proxies, then
 // we set the jumps around the proxies for any outbound masking to an alias

 std::string proxy_jmph = "iptables -t nat ";
 std::string proxy_jmpt = " -m mark --mark 0x80000000/0x80000000 -j RETURN";

 // the match mark mask does not correctly mask for some reason
 // the position of flag and mask might be reversed

 if (chkproxy())
 {
  rmdupes (ipb, proxy_jmph + "-D jmpim" + proxy_jmpt);
  rmdupes (ipb, proxy_jmph + "-D jmpp3scan" + proxy_jmpt);
  rmdupes (ipb, proxy_jmph + "-D jmpsip" + proxy_jmpt);
  rmdupes (ipb, proxy_jmph + "-D jmpsquid" + proxy_jmpt);
 }

 if (mark_seq > 0x800)
 {
  rmdupes (ipb, proxy_jmph + "-I jmpim" + proxy_jmpt);
  rmdupes (ipb, proxy_jmph + "-I jmpp3scan" + proxy_jmpt);
  rmdupes (ipb, proxy_jmph + "-I jmpsip" + proxy_jmpt);
  rmdupes (ipb, proxy_jmph + "-I jmpsquid" + proxy_jmpt);
 }
 //=============================================================================>
 // Read the rules, in sequence from "configfile" and build

 for (int line = fwdconf.first(); line == 0; line = fwdconf.next())
 {
  const std::string & f_input   = fwdconf[1];
  const std::string & f_source  = fwdconf[2];
  const std::string & f_dport   = fwdconf[3];
  const std::string & f_output  = fwdconf[4];
  const std::string & f_fwdest  = fwdconf[5];
  const std::string & f_fwdport = fwdconf[6];
  const std::string & f_proto   = fwdconf[7];
  const std::string & f_action  = fwdconf[8];
  const std::string & f_enabled = fwdconf[9];

  if (f_input.find_first_not_of(INTERFACE) != std::string::npos &&
   (f_input.find_first_not_of(INTERFACE_ALIAS) != std::string::npos) &&
    f_input != "any")
  {
   response = "Abort, bad input interface: (" + f_input + ") rule number " +
    fwdconf[0];
   return errrpt (response);
  }
  if (f_output.find_first_not_of(INTERFACE) != std::string::npos &&
   (f_output.find_first_not_of(INTERFACE_ALIAS) != std::string::npos) &&
    f_output != "any")
  {
   response = "Abort, bad output interface: " + f_output + " rule number " +
    fwdconf[0];
   return errrpt (response);
  }
  if (f_proto.find_first_not_of(NUMBERS) != std::string::npos &&
   f_proto != "all")
  {
   response = "Abort, bad protocol: (" + f_proto + ") rule number " + fwdconf[0];
   return errrpt (response);
  }
  if (f_dport.find_first_not_of(NUMBERS_COLON) != std::string::npos)
  {
   response = "Abort, bad initial destination port: (" + f_dport +
    ") rule number " + fwdconf[0];
   return errrpt (response);
  }
  // First operation is to remove negation, if present

  negated_source = false;
  if ((p = f_source.find_first_of("! ")) != std::string::npos &&
   (n = f_source.find_first_not_of("! ")) != std::string::npos)
  {
     negated_source = true;
     temp_source = f_source;
     temp_source = temp_source.erase(p, n - p);
  }
  else temp_source = f_source;

  if (temp_source.find_first_not_of(IP_NUMBERS) != std::string::npos &&
   temp_source.find_first_not_of(MAC_HEX) != std::string::npos)
  {
   response = "Abort, bad source IP or MAC: (" + f_source + ") rule number " +
    fwdconf[0];
   return errrpt (response);
  }
  if (f_fwdest.find_first_not_of(IP_NUMBERS) != std::string::npos)
  {
   response = "Abort, bad new destination IP: (" + f_fwdest + ") rule number " +
    fwdconf[0];
   return errrpt (response);
  }
  if (f_fwdport.find_first_not_of(NUMBERS_COLON) != std::string::npos)
  {
   response = "Abort, bad new destination port: (" + f_fwdport +
    ") rule number " + fwdconf[0];
   return errrpt (response);
  }
  if (f_action != "REJECT" && f_action != "RETURN" && f_action != "ACCEPT" &&
   f_action  != "DROP"   &&	f_action != "LOG")
  {
   response = "Abort, bad action: (" + f_action + ") rule number " + fwdconf[0];
   return errrpt (response);
  }
  if (f_enabled == "on")
  {
   // ==========================================================================>
   // we allow red bouncing by specifying that it comes from * interface
   // because bouncing requires that DNAT and SNAT be done on the packets
   // specifying an interface on bounces is not possible, the source is the
   // destination for bounces, if the source must be limited on bounces,
   // use an IP limitation
   // ==========================================================================>
   // Here we create the source strings, or leave null if unused

   forwarding = false;
   in_dest = "";
   if (f_input.find(red_if) != std::string::npos)
   {
    if (f_proto == "1" || f_proto == "6" || f_proto == "17" ||
     f_proto == "47" || f_proto == "50" || f_proto == "51")
    {
     forwarding = true;

     // ICMP:1 TCP:6 UDP:17 GRE:47 ESP:50 AH:51   <---Forwarded protocols

     in_dest = localip.str();

     // default IP for the actual red interface, changed only for aliases
     // If it is an alias

     if (f_input.find(":") != std::string::npos)
     {
      for (int line = aliases.first(); line == 0; line = aliases.next())

      // forwarding from the red interface we need to find the IP
      {
       const std::string & f_ifalias = aliases[1];
       const std::string & f_ipaddress = aliases[3];

       if ((f_input == f_ifalias  && aliases[7] == "on"))
        in_dest = f_ipaddress;
      }
     }
     if (in_dest.find_first_not_of(IP_NUMBERS) != std::string::npos &&
      in_dest.find_first_of("/") != std::string::npos)
     {
      response = "Abort, could not find match for interface (" + f_input +
       ") and IP (" + in_dest +
        ") to construct a forwarding rule in rule number " + fwdconf[0];
      return errrpt (response);
     }
    }  //  <<== End of protocol
   }  //  <<== End of Red IF

   ifc_in_out = "";
   if (f_input != "any" && ! forwarding)

   // If it is not "any" and not being forwarded set the input interface
   {
    ifc_in_out = f_input;

    // If it is an alias interface, truncate the string starting with the colon

    if ((n = ifc_in_out.find_first_of(":")) != std::string::npos)
     ifc_in_out.erase(n, 4);

    ifc_in_out = " -i " + ifc_in_out;
   }
   ifc_out_out = "";
   if (f_output != "any" && f_output != "")
   {
    ifc_out_out = f_output;

    if ((n = ifc_out_out.find_first_of(":")) != std::string::npos)
     ifc_out_out.erase(n, 4);

    ifc_out_out = " -o " + ifc_out_out;
   }
   prot_out = "";
   if (f_proto != "all" && f_proto != "") prot_out = " -p " + f_proto;

   dest_out = "";
   if (in_dest != "") dest_out = " -d " + in_dest;

   dport_out = "";
   if (f_dport !=  "0" && f_dport !=  "") dport_out = " --dport " + f_dport;

   translating = false;
   fwdport_out = "";
   fwdportdest = "";
   if (f_fwdport !=  "0" && f_fwdport !=  "")
   {
    translating = true;
    fwdport_out = " --dport " + f_fwdport;
    fwdportdest = f_fwdport;

    if ((n = fwdportdest.find_first_of(":")) != std::string::npos)
     fwdportdest.replace(n, 1, "-");

    fwdportdest = ":" + fwdportdest;
   }

   fwdest_out = "";
   dnat_out = "";
   if (translating || forwarding)
   {
    if (f_fwdest != "" &&
      f_fwdest.find_first_of("/") == std::string::npos)

    // an IP is being forwarded, but we must have a destination IP to
    // forward to for DNAT to be sensible
    {
     fwdest_out = " -d " + f_fwdest;
     dnat_out = " -j DNAT --to-destination " + f_fwdest + fwdportdest;
    }
    // If we expected to build a DNAT rule and failed, the IP is not singular

    if (dnat_out == "")
    {
     response = "Abort, bad new destination IP (" + f_fwdest +
      "), must be single IP in rule number " + fwdconf[0];
     return errrpt (response);
    }
    // translation requires the same IP in the DNAT initial destination

    if (! forwarding) dest_out = fwdest_out;
   }
   srcipmac_out = "";
   if (temp_source.find_first_not_of(IP_NUMBERS) == std::string::npos)
   {
    srcipmac_out = " -s " + temp_source;
   }
   if (temp_source.find_first_not_of(MAC_HEX) == std::string::npos)
   {
    srcipmac_out = " -m mac --mac-source " + temp_source;
   }
    // must be a space between "!" and the descriptor
    if (negated_source) srcipmac_out = " ! " + srcipmac_out;

   tgt_out = " -j " + f_action;
   if (f_action == "LOG") tgt_out = " -j LOG --log-prefix ..FFC..";

   // if we aren't going to DNAT we still need some information in portfwf

   if (! translating && dport_out != "") fwdport_out = dport_out;

   if (dnat_out == "" && f_fwdest != "") fwdest_out = " -d " + f_fwdest;

   // ==========================================================================>
   // Here we get down to the business of creating the rules from the strings

   if (forwarding || translating) rmdupes (ipb, "iptables -t nat -A portfw " +
    ifc_in_out + prot_out + srcipmac_out + dest_out + dport_out + dnat_out);

   rmdupes (ipb, "iptables -t filter -A portfwf -m state --state NEW" +
    ifc_out_out + prot_out + srcipmac_out + fwdest_out +
     fwdport_out + tgt_out);

   // In the INPUT chain we should not ACCEPT since EXTACCESS should be the
   // source for that type of rule, and only process rules that are not
   // forwarding or translating rules, meaning no specific output interface

   if (tgt_out == " -j ACCEPT") tgt_out = " -j RETURN";

   // Note: If the destination interface is specified then we don't create
   // a rule.  This allows the proxies to bypass a block rule for outbounds
   // which may be blocked by an additional specific rule with the Any
   // interface specified.  Another option explored was to skip only ACCEPT
   // rules, but that has limited usability as well.

   if (ifc_out_out == "")
    rmdupes (ipb, "iptables -t filter -A portfwi -m state --state NEW" +
     ifc_in_out + prot_out + srcipmac_out + dport_out + tgt_out);

   // ==========================================================================>
   // Here we create rules for bouncing if the input interface is null and
   // there has been a DNAT for the red interface, we skip translating DNAT

   if (forwarding)
   {
    std::string forward_pre = "iptables -t mangle -A portfwb -i ";
    std::string forward_post = " -j MARK --set-mark ";

    if (green_if  != "") rmdupes (ipb, forward_pre + green_if  + dest_out +
     forward_post +  conn_green);

    if (purple_if != "") rmdupes (ipb, forward_pre + purple_if + dest_out +
     forward_post + conn_purple);

    if (orange_if != "") rmdupes (ipb, forward_pre + orange_if + dest_out +
     forward_post + conn_orange);

    bounce_type = true;
   }

  }//   <<==== End of enabled

 }//   <<==== End of reading portfw/config file

 //=============================================================================>
 // The rules have been created, now we need to allow bounces, if we are doing
 // any portforwarding that allows bouncing

 if (bounce_type)
 {
  // We only need to SNAT those packets that came in the same interface that
  // they are going out on to ensure the return path is through the interface

  std::string pfw_post_pre = "iptables -t nat -A portfw_post -m mark --mark ";
  std::string pfw_post_post = " -j SNAT --to-source ";

  if (green_if != "")
   rmdupes (ipb, pfw_post_pre + conn_green  + " -o " + green_if  + pfw_post_post +
    green_ifip);

  if (purple_if != "")
   rmdupes (ipb, pfw_post_pre + conn_purple + " -o " + purple_if + pfw_post_post +
    purple_ifip);

  if (orange_if != "")
   rmdupes (ipb, pfw_post_pre + conn_orange + " -o " + orange_if + pfw_post_post +
    orange_ifip);
 }
 //=============================================================================>
 // Pass the built up vector of strings to ipbatch to build IPTables entries

 error = ipbatch(ipb);

 if (error) response = "Abort flushing rules to IPTables";
 return errrpt (response);
}
//#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@>
int set_xtaccess(std::vector<std::string> & parameters, std::string & response)
{
 std::string ifacefile    = "/var/smoothwall/red/iface";
 std::string cmdprefix    = "/var/smoothwall";
 std::string configfile   = cmdprefix + "/xtaccess/config";
 std::string aliasfile    = cmdprefix + "/portfw/aliases";

 ConfigSTR ifacef(ifacefile);
 ConfigCSV config(configfile);
 ConfigCSV aliases(aliasfile);

 std::vector<std::string> ipb;
 std::string red_ip            = "";
 std::string iface             = ifacef.str();
 std::string destination       = "";
 std::string dport_out         = "";
 int error                     = 0;

 // preset the response to a success, changed only on error, always return zero

 response = "External Access Rules set";

 if (ifacef.str() == "")
 {
  response = "Abort, could not open red local interface file (" + ifacefile + ")";
  return errrpt (response);
 }
 if (iface.find_first_not_of(INTERFACE) != std::string::npos)
 {
  response = "Abort, bad interface: " + iface;
  return errrpt (response);
 }

 rmdupes(ipb, "iptables -t filter -F xtaccess");
 rmdupes(ipb, "iptables -t nat -F portfw_pre");

 //=============================================================================>
 // Any destination IP that is local and not forwarded goes to us through INPUT

 for (int line = config.first(); line == 0; line = config.next())
 {
  const std::string & alias    = config[0];
  const std::string & protocol = config[1];
  const std::string & remip    = config[2];
  const std::string & locport  = config[3];
  const std::string & enabled  = config[4];

  if (protocol.find_first_not_of(NUMBERS) != std::string::npos)
  {
   response = "Abort, bad protocol: " + protocol;
   return errrpt (response);
  }
  if (remip.find_first_not_of(IP_NUMBERS) != std::string::npos)
  {
   response = "Abort, bad remote IP: " + remip;
   return errrpt (response);
  }
  if (locport.find_first_not_of(NUMBERS_COLON) != std::string::npos)
  {
   response = "Abort, bad port: " + locport;
   return errrpt (response);
  }
  dport_out = "";
  if (locport !=  "0" && locport !=  "") dport_out = " --dport " + locport;

  red_ip = "";
  for (int aline = aliases.first(); aline == 0; aline = aliases.next())

  // we need to find the alias IP of the red interface
  {
   const std::string & f_ifalias = aliases[1];
   const std::string & f_ipaddress = aliases[3];

   if (alias == f_ifalias)
   {
    red_ip = f_ipaddress;
    break;
   }
  }
  if (red_ip == "")
  {
   response = "Abort, could not find an alias match in (" + configfile + ") with (" +
    aliasfile + ") for an IP in the XTAccess rule";
   return errrpt(response);
  }
  destination = " -d " + red_ip;

  //============================================================================>
  // This only creates the rules if they are present and enabled, the alias
  // may be disabled which would make the rule ineffective since the IP would
  // not be present in ifconfig

  if (enabled == "on")
  {
   rmdupes(ipb, "iptables -t filter -A xtaccess -i " + iface + " -d " + red_ip + 
    " -p " + protocol + dport_out + " -s " + remip + " -j ACCEPT");
  }
 }

 error = ipbatch(ipb);

 if (error) response = "ipbatch failure";

 return errrpt (response);
}
Example #9
0
int set_xtaccess(std::vector<std::string> & parameters, std::string & response)
{
	int error = 0;
	ConfigSTR ifacef("/var/smoothwall/red/iface");
	ConfigCSV config("/var/smoothwall/xtaccess/config");
	std::vector<std::string>ipb;
	std::string::size_type n;
	std::string iface = ifacef.str();

	if (iface.substr(0, 3) == "ppp" || iface.substr(0, 4) == "ippp")
		iface = ""; // ignore ppp
	if (iface != "" && ((n = iface.find_first_not_of(LETTERS_NUMBERS)) != std::string::npos))
	{
		response = "Bad iface: " + iface; 
		error = 1;
		goto EXIT;
	}
	
	ipb.push_back("iptables  -F xtaccess");

	for (int line = config.first(); line == 0; line = config.next())
	{
		const std::string & protocol = config[0];
		const std::string & remip = config[1];
		const std::string & locport = config[2];
		const std::string & enabled = config[3];

		// are we complete?
		if (protocol == "" || remip == "" || locport == "" || enabled == "")
			break;

		if ((n = protocol.find_first_not_of(LETTERS)) != std::string::npos)
		{
			response = "Bad protocol: " + protocol;
			error = 1;
			goto EXIT;
		}
		if ((n = remip.find_first_not_of(IP_NUMBERS)) != std::string::npos)
		{
			response = "Bad remote IP: " + remip;
			error = 1;
			goto EXIT;
		}
		if ((n = locport.find_first_not_of(NUMBERS_COLON)) != std::string::npos)
		{
			response = "Bad port: " + locport;
			error = 1;
			goto EXIT;
		}
		if (enabled == "on")
		{
			ipb.push_back("iptables -A xtaccess -i ppp0 -p " + protocol + 
				" -s " + remip + 
				" --destination-port " + locport + " -j ACCEPT");
			ipb.push_back("iptables -A xtaccess -i ippp0 -p " + protocol + 
				" -s " + remip + 
				" --destination-port " + locport + " -j ACCEPT");

			if (iface != "")
			{
				ipb.push_back("iptables -A xtaccess -i " + iface + " -p " + protocol + 
					" -s " + remip + 
					" --destination-port " + locport + " -j ACCEPT");
			}		
		}
	}

	error = ipbatch(ipb);
	if (error)
		response = "ipbatch failure";
	else
		response = "xtaccess set";

EXIT:
	return error;
}
Example #10
0
int set_internal(std::vector<std::string> & parameters, std::string & response)
{
	int error = 0;
	ConfigCSV config("/var/smoothwall/dmzholes/config");
	std::vector<std::string>ipb;
	std::string::size_type n;
	
	load_portlist();

	ipb.push_back("iptables -F dmzholes");

	for (int line = config.first(); line == 0; line = config.next())
	{
		const std::string & protocol = config[0];
		const std::string & locip = config[1];
		const std::string & remip = config[2];
		const std::string & remport = config[3];
		const std::string & enabled = config[4];

		// are we complete?
		if (protocol == "" || locip == "" || remip == "" || remport == "" || enabled == "")
			continue;

		if ((n = protocol.find_first_not_of(LETTERS)) != std::string::npos)
		{
			response = "Bad protocol: " + protocol;
			error = 1;
			return error;
		}
		if ((n = locip.find_first_not_of(IP_NUMBERS)) != std::string::npos)
		{
			response = "Bad local IP: " + locip;
			error = 1;
			return error;
		}
		if ((n = remip.find_first_not_of(IP_NUMBERS)) != std::string::npos)
		{
			response = "Bad remote IP: " + remip;
			error = 1;
			return error;
		}
		
		if (enabled == "on")
		{
			if ((n = remport.find_first_not_of(NUMBERS_COLON)) != std::string::npos)
			{
				if (portlist[remport.c_str()].size() > 0)
				{
					/* it's a mapped port! */
					std::vector<std::string> & vect = portlist[remport.c_str()];
					for (std::vector<std::string>::iterator i = vect.begin();
						i != vect.end(); i++)
					{
						std::string nport = *i;
						ipb.push_back("iptables -A dmzholes -m state --state NEW -p " + protocol + " -s " + locip + " -d " + remip + " --dport  " + nport + " -j ACCEPT");
					}
				}
				else
				{
					response = "Bad remote port: " + remport;
					error = 1;
					return error;
				}
			}
			else
				ipb.push_back("iptables -A dmzholes -m state --state NEW -p " + protocol + " -s " + locip + " -d " + remip + " --dport  " + remport + " -j ACCEPT");
		}
	}

	error = ipbatch(ipb);

	if (error)
		response = "ipbatch failure";
	else
		response = "DMZ Holes set";

	return (error);
}
Example #11
0
int set_outgoing(std::vector<std::string> & parameters, std::string & response)
{
	int error = 0;
	ConfigVAR settings("/var/smoothwall/outgoing/settings");
	ConfigCSV config("/var/smoothwall/outgoing/config");
	ConfigCSV machineconfig("/var/smoothwall/outgoing/machineconfig");
	std::vector<std::string>ipb;
	std::string::size_type n;
	
	load_portlist();

	ipb.push_back("iptables -F outgreen\n");
	ipb.push_back("iptables -F outorange");
	ipb.push_back("iptables -F outpurple");

	for (int line = config.first(); line == 0; line = config.next())
	{
		const std::string & colour = config[0];
		const std::string & enabled = config[1];
		const std::string & port = config[2];

		// are we complete?
		if (colour == "" || port == "" || enabled == "")
			continue;

		if (!(colour == "GREEN" || colour == "ORANGE" || colour == "PURPLE"))
		{
			response = "Bad colour: " + colour;
			error = 1;
			return error;
		}

		std::string chain = "out" + colour;
		std::transform(chain.begin(), chain.end(), chain.begin(), tolower);
		
		std::string action = settings[colour.c_str()];
		if (action == "") action = "REJECT";
		
		if (enabled == "on")
		{
			if ((n = port.find_first_not_of(NUMBERS_COLON)) != std::string::npos)
			{
				if (portlist[port.c_str()].size() > 0)
				{
					/* it's a mapped port! */
					std::vector<std::string> & vect = portlist[port.c_str()];
					for (std::vector<std::string>::iterator i = vect.begin();
						i != vect.end(); i++)
					{
						std::string nport = *i;
						ipb.push_back("iptables -A " + chain + " -p tcp --dport " + nport + " -j " + action);
						ipb.push_back("iptables -A " + chain + " -p udp --dport " + nport + " -j " + action);
					}
				}
				else
				{
					response = "Bad port: " + port;
					error = 1;
					return error;
				}
			} 
			else
			{
				ipb.push_back("iptables -A " + chain + " -p tcp --dport " + port + " -j " + action);
				ipb.push_back("iptables -A " + chain + " -p udp --dport " + port + " -j " + action);
			}
		}
	}

	if (settings["GREEN"] != "ACCEPT") ipb.push_back("iptables -A outgreen -j ACCEPT");
	if (settings["ORANGE"] != "ACCEPT") ipb.push_back("iptables -A outorange -j ACCEPT");
	if (settings["PURPLE"] != "ACCEPT") ipb.push_back("iptables -A outpurple -j ACCEPT");

	ipb.push_back("iptables -F allows");

	for (int line = machineconfig.first(); line == 0; line = machineconfig.next())
	{
		const std::string & ip = machineconfig[0];
		const std::string & enabled = machineconfig[1];

		// are we complete?
		if (ip == "" || enabled == "")
			continue;
	
		if ((n = ip.find_first_not_of(IP_NUMBERS)) != std::string::npos)
		{
			response = "Bad IP: " + ip;
			error = 1;
			return error;
		}
		
		if (enabled == "on")
			ipb.push_back("iptables -A allows -s " + ip + " -j ACCEPT");
	}
	
	error = ipbatch(ipb);
	if (error)
		response = "ipbatch failure";
	else
		response = "Outbound ports set";

	return error;
}
Example #12
0
int set_incoming(std::vector<std::string> & parameters, std::string & response)
{
	int error = 0;

	std::string::size_type n;
	std::vector<std::string>ipbfilter;
	std::vector<std::string>ipbnat;
	std::vector<std::string>ipbmangle;

	ConfigSTR localip("/var/smoothwall/red/local-ipaddress");
	ConfigSTR iface("/var/smoothwall/red/iface");
	ConfigCSV fwdfile("/var/smoothwall/portfw/config");
	ConfigVAR ethernet("/var/smoothwall/ethernet/settings");

	if ((error = (localip.str() == "")))
	{
		response = "Couldn't open local IP file";
		return error;
	}
	// carry on
	if ((n = localip.str().find_first_not_of(IP_NUMBERS)) != std::string::npos) 
	{
		// illegal characters
		response = "Bad local IP: " + localip.str();
		error = 1;
		return error;
	}
	if ((error = (iface.str() == "")))
	{
		response = "Couldn't open iface file";
		return error;
	}
	// carry on
	if ((n = iface.str().find_first_not_of(LETTERS_NUMBERS)) != std::string::npos) 
	{
		// illegal characters
		response = "Bad iface: " + iface.str();
		error = 1;
		return error;
	}

	ipbfilter.push_back("iptables -t filter -F portfwf");
	ipbnat.push_back("iptables -t nat -F portfw");
	ipbmangle.push_back("iptables -t mangle -F portfwb");

	// iterate the CSV
	for (int line = fwdfile.first(); line == 0; line = fwdfile.next())
	{
		std::string remdouble;
		const std::string & protocol = fwdfile[0];
		const std::string & extip = fwdfile[1];
		const std::string & locport = fwdfile[2];
		const std::string & remip = fwdfile[3];

		// this last one want to change maybe
		std::string remport = fwdfile[4];
		const std::string & enabled = fwdfile[5];
		if ((n = protocol.find_first_not_of(LETTERS)) != std::string::npos)
		{
			response = "Bad protocol: " + protocol;
			error = 1;
			return error;
		}
		if ((n = extip.find_first_not_of(IP_NUMBERS)) != std::string::npos)
		{
			response = "Bad external IP: " + extip;
			error = 1;
			return error;
		}
		if ((n = locport.find_first_not_of(NUMBERS_COLON)) != std::string::npos)
		{
			response = "Bad local port: " + locport;
			error = 1;
			return error;
		}
		if ((n = remip.find_first_not_of(IP_NUMBERS)) != std::string::npos)
		{
			response = "Bad remote IP: " + remip;
			error = 1;
			return error;
		}
		if ((n = remport.find_first_not_of(NUMBERS)) != std::string::npos)
		{
			response = "Bad remote port: " + remport;
			error = 1;
			return error;
		}

		if (enabled == "on")
		{
			if (remport == "0")
				remport = locport;
			// if locport does not have : or originally remport not zero 
			if(locport.find_first_of(":") == std::string::npos || fwdfile[4] != "0")
				remdouble = remip + ":" + remport;
			else 
				remdouble = remip;

			ipbfilter.push_back("iptables -t filter -A portfwf -m state --state NEW -p " + protocol +
				" -s " + extip +
				" -d " + remip +
				" --dport " + remport + " -j ACCEPT");
			ipbnat.push_back("iptables -t nat -A portfw -p " + protocol +
				" -s " + extip +  
				" -d " + localip.str() +  			
				" --dport " + locport + " -j DNAT --to " + remdouble);
		}
	}

	/* Rules to detect bouncing port forwarding */
	int mark = 0;
	std::string insideinterface;
	while (mark++ < 3)
	{
		switch (mark)
		{
			case 1: insideinterface = ethernet["GREEN_DEV"];  break;
			case 2: insideinterface = ethernet["ORANGE_DEV"]; break;
			case 3: insideinterface = ethernet["PURPLE_DEV"]; break;
			default: break;
		}

		if (insideinterface != "")
		{
			ipbmangle.push_back("iptables -t mangle -A portfwb -i " + insideinterface +
				" -d " + localip.str() + " -j MARK --set-mark " + stringprintf("%d", mark));
		}
	}

	error = ipbatch(ipbfilter);
	if (error)
	{
		response = "ipbatch failure (filter)";
		return error;
	}

	error = ipbatch(ipbnat);
	if (error)
	{
		response = "ipbatch failure (nat)";
		return error;
	}
	
	error = ipbatch(ipbmangle);
	if (error)
	{
		response = "ipbatch failure (mangle)";
		return error;
	}
	
	response = "Portfw rules set";

	return (error);
}