policy.cpp

Go to the documentation of this file.
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 

Generated on Wed Sep 5 15:49:28 2007 for Vidalia by  doxygen 1.5.3