00001 /**************************************************************** 00002 * Vidalia is distributed under the following license: 00003 * 00004 * Copyright (C) 2006, Matt Edman, Justin Hipple 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, 00019 * Boston, MA 02110-1301, USA. 00020 ****************************************************************/ 00021 00022 /** 00023 * \file policy.cpp 00024 * \version $Id: policy.cpp 1563 2006-12-26 06:06:04Z edmanm $ 00025 * \brief Exit policy parsing 00026 */ 00027 00028 #include <QStringList> 00029 00030 #include "policy.h" 00031 00032 00033 /** Default constructor. Creates an AcceptAll policy. */ 00034 Policy::Policy() 00035 { 00036 _action = Accept; 00037 _address = QHostAddress::Any; 00038 _fromPort = _toPort = 0; 00039 _mask = 0; 00040 } 00041 00042 /** Constructor. Creates a new Policy object from the given string. */ 00043 Policy::Policy(QString policy) 00044 { 00045 /* Set the defaults */ 00046 _action = Accept; 00047 _address = QHostAddress::Any; 00048 _fromPort = _toPort = 0; 00049 _mask = 0; 00050 00051 /* Parse the given string to override the defaults. */ 00052 fromString(policy); 00053 } 00054 00055 /** Constructor. Creates a new Policy object from the string parts. */ 00056 Policy::Policy(QString action, QString address, QString ports) 00057 { 00058 /* Set the defaults */ 00059 _action = Accept; 00060 _address = QHostAddress::Any; 00061 _fromPort = _toPort = 0; 00062 _mask = 0; 00063 00064 fromString(action + " " + address + ":" + ports); 00065 } 00066 00067 /** Constructor. Creates a new Policy object depending on the specified 00068 * special policy type. */ 00069 Policy::Policy(SpecialPolicy policy) 00070 { 00071 _action = (policy == AcceptAll ? Accept : Reject); 00072 _address = QHostAddress::Any; 00073 _fromPort = _toPort = 0; 00074 _mask = 0; 00075 } 00076 00077 /** Constructor. Creates a new policy object based on the given rules. */ 00078 Policy::Policy(Action action, QHostAddress addr, uchar mask, 00079 quint16 fromPort, quint16 toPort) 00080 { 00081 _action = action; 00082 _address = addr; 00083 _mask = mask; 00084 _fromPort = fromPort; 00085 _toPort = (toPort >= fromPort ? toPort : fromPort); 00086 } 00087 00088 /** Returns true if this policy is identical to <b>policy</b>. */ 00089 bool 00090 Policy::operator==(const Policy &policy) const 00091 { 00092 return ((this->_action == policy._action) && 00093 (this->_address == policy._address) && 00094 (this->_mask == policy._mask) && 00095 (this->_fromPort == policy._fromPort) && 00096 (this->_toPort == policy._toPort)); 00097 } 00098 00099 /** Returns true if this policy matches <b>policy</b>. For example, if this 00100 * policy is "reject *:6660-6669" and <b>policy</b> is "reject *:6662-6664", 00101 * this will return true. For strict comparison, use the == operator. */ 00102 bool 00103 Policy::matches(const Policy &policy) const 00104 { 00105 /* This doesn't take into account addr/mask matches yet */ 00106 return ((this->_action == policy._action) && 00107 (this->_address == policy._address) && 00108 (this->_mask == policy._mask) && 00109 (this->_fromPort <= policy._fromPort) && 00110 (this->_toPort >= policy._toPort)); 00111 } 00112 00113 /** Parses the given exit policy string. */ 00114 void 00115 Policy::fromString(QString policy) 00116 { 00117 /* Separate the action and the address/mask/port info */ 00118 QStringList ruleParts = policy.split(" "); 00119 _action = toAction(ruleParts.at(0)); 00120 00121 /* If some address/mask/port stuff was specified, parse it. */ 00122 if (ruleParts.size() > 1) { 00123 QStringList addrParts = ruleParts.at(1).split(":"); 00124 00125 /* Parse the address and mask (if specified) */ 00126 QString addr = addrParts.at(0); 00127 _address.setAddress(addr.mid(0, addr.indexOf("/"))); 00128 if (_address.isNull()) { 00129 _address = QHostAddress::Any; 00130 } 00131 if (addr.contains("/")) { 00132 _mask = addr.mid(addr.indexOf("/")+1).toUInt(); 00133 } 00134 00135 /* Parse the specified port range (if specified) */ 00136 if (addrParts.size() > 1) { 00137 QString ports = addrParts.at(1); 00138 _fromPort = ports.mid(0, ports.indexOf("-")).toUInt(); 00139 if (ports.contains("-")) { 00140 _toPort = ports.mid(ports.indexOf("-")+1).toUInt(); 00141 } else { 00142 _toPort = _fromPort; 00143 } 00144 } 00145 } 00146 } 00147 00148 /** Converts this policy to a form Tor understands. The format is: 00149 * "accept|reject ADDR[/MASK][:PORT]" 00150 * 00151 * PORT can be a single port number, an interval of ports "FROM_PORT-TO_PORT", 00152 * or "*". If PORT is omitted, that means "*" 00153 */ 00154 QString 00155 Policy::toString() const 00156 { 00157 QString act = (_action == Accept ? "accept" : "reject"); 00158 return act + " " + address() + ":" + ports(); 00159 } 00160 00161 /** Converts the given action to a string. This function tolerates both the 00162 * translated and untranslated forms of the string "accept" and "reject". */ 00163 Policy::Action 00164 Policy::toAction(QString action) 00165 { 00166 action = action.toLower(); 00167 if (action == tr("accept") || action == "accept") { 00168 return Accept; 00169 } 00170 return Reject; 00171 } 00172 00173 /** Returns the action associated with this policy. NOTE: This string will be 00174 * translated to whatever the current language setting is. */ 00175 QString 00176 Policy::action() const 00177 { 00178 return (_action == Accept ? tr("accept") : tr("reject")); 00179 } 00180 00181 /** Returns the address (and mask, if specified) for this policy. */ 00182 QString 00183 Policy::address() const 00184 { 00185 QString addrString; 00186 00187 if (_mask) { 00188 addrString = _address.toString() + "/" + QString::number(_mask); 00189 } else if (_address == QHostAddress::Any || _address.isNull()) { 00190 addrString = "*"; 00191 } else { 00192 addrString = _address.toString(); 00193 } 00194 return addrString; 00195 } 00196 00197 /** Returns the port (or port range, if specified) for this policy. */ 00198 QString 00199 Policy::ports() const 00200 { 00201 QString ports = (_fromPort ? QString::number(_fromPort) : "*"); 00202 if (_fromPort && (_toPort > _fromPort)) { 00203 ports += "-" + QString::number(_toPort); 00204 } 00205 return ports; 00206 } 00207