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 1238 2006-09-25 17:50:57Z 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 _fromPort = fromPort; 00084 _toPort = toPort; 00085 _mask = mask; 00086 } 00087 00088 /** Overloads the == operator. */ 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 /** Parses the given exit policy string. */ 00100 void 00101 Policy::fromString(QString policy) 00102 { 00103 /* Separate the action and the address/mask/port info */ 00104 QStringList ruleParts = policy.split(" "); 00105 _action = toAction(ruleParts.at(0)); 00106 00107 /* If some address/mask/port stuff was specified, parse it. */ 00108 if (ruleParts.size() > 1) { 00109 QStringList addrParts = ruleParts.at(1).split(":"); 00110 00111 /* Parse the address and mask (if specified) */ 00112 QString addr = addrParts.at(0); 00113 _address.setAddress(addr.mid(0, addr.indexOf("/"))); 00114 if (addr.contains("/")) { 00115 _mask = addr.mid(addr.indexOf("/")+1).toUInt(); 00116 } 00117 00118 /* Parse the specified port range (if specified) */ 00119 if (addrParts.size() > 1) { 00120 QString ports = addrParts.at(1); 00121 _fromPort = ports.mid(0, ports.indexOf("-")).toUInt(); 00122 if (ports.contains("-")) { 00123 _toPort = ports.mid(ports.indexOf("-")+1).toUInt(); 00124 } 00125 } 00126 } 00127 } 00128 00129 /** Converts this policy to a form Tor understands. The format is: 00130 * "accept|reject ADDR[/MASK][:PORT]" 00131 * 00132 * PORT can be a single port number, an interval of ports "FROM_PORT-TO_PORT", 00133 * or "*". If PORT is omitted, that means "*" 00134 */ 00135 QString 00136 Policy::toString() 00137 { 00138 QString act = (_action == Accept ? "accept" : "reject"); 00139 return act + " " + address() + ":" + ports(); 00140 } 00141 00142 /** Converts the given action to a string. This function tolerates both the 00143 * translated and untranslated forms of the string "accept" and "reject". */ 00144 Policy::Action 00145 Policy::toAction(QString action) 00146 { 00147 action = action.toLower(); 00148 if (action == tr("accept") || action == "accept") { 00149 return Accept; 00150 } 00151 return Reject; 00152 } 00153 00154 /** Returns the action associated with this policy. NOTE: This string will be 00155 * translated to whatever the current language setting is. */ 00156 QString 00157 Policy::action() 00158 { 00159 return (_action == Accept ? tr("accept") : tr("reject")); 00160 } 00161 00162 /** Returns the address (and mask, if specified) for this policy. */ 00163 QString 00164 Policy::address() 00165 { 00166 QString addrString; 00167 00168 if (_mask) { 00169 if (_address.isNull()) { 00170 _address = QHostAddress::Any; 00171 } 00172 addrString = _address.toString() + "/" + QString::number(_mask); 00173 } else if (_address == QHostAddress::Any || _address.isNull()) { 00174 addrString = "*"; 00175 } else { 00176 addrString = _address.toString(); 00177 } 00178 return addrString; 00179 } 00180 00181 /** Returns the port (or port range, if specified) for this policy. */ 00182 QString 00183 Policy::ports() 00184 { 00185 QString ports = (_fromPort ? QString::number(_fromPort) : "*"); 00186 if (_fromPort && _toPort) { 00187 ports += "-" + QString::number(_toPort); 00188 } 00189 return ports; 00190 } 00191