policy.cpp

Go to the documentation of this file.
00001 /*
00002 **  This file is part of Vidalia, and is subject to the license terms in the
00003 **  LICENSE file, found in the top level directory of this distribution. If you
00004 **  did not receive the LICENSE file with this file, you may obtain it from the
00005 **  Vidalia source package distributed by the Vidalia Project at
00006 **  http://www.vidalia-project.net/. No part of Vidalia, including this file,
00007 **  may be copied, modified, propagated, or distributed except according to the
00008 **  terms described in the LICENSE file.
00009 */
00010 
00011 /*
00012 ** \file policy.cpp
00013 ** \version $Id: policy.cpp 2362 2008-02-29 04:30:11Z edmanm $
00014 ** \brief Exit policy parsing
00015 */
00016 
00017 #include <QStringList>
00018 
00019 #include "policy.h"
00020 
00021 
00022 /** Default constructor. Creates an AcceptAll policy. */
00023 Policy::Policy()
00024 {
00025   _action   = Accept;
00026   _address  = QHostAddress::Any;
00027   _fromPort = _toPort = 0;
00028   _mask = 0;
00029 }
00030 
00031 /** Constructor. Creates a new Policy object from the given string. */
00032 Policy::Policy(QString policy)
00033 {
00034   /* Set the defaults */
00035   _action   = Accept;
00036   _address  = QHostAddress::Any;
00037   _fromPort = _toPort = 0;
00038   _mask = 0;
00039  
00040   /* Parse the given string to override the defaults. */
00041   fromString(policy);
00042 }
00043 
00044 /** Constructor. Creates a new Policy object from the string parts. */
00045 Policy::Policy(QString action, QString address, QString ports)
00046 {
00047   /* Set the defaults */
00048   _action   = Accept;
00049   _address  = QHostAddress::Any;
00050   _fromPort = _toPort = 0;
00051   _mask = 0;
00052  
00053   fromString(action + " " + address + ":" + ports);
00054 }
00055 
00056 /** Constructor. Creates a new Policy object depending on the specified
00057  * special policy type. */
00058 Policy::Policy(SpecialPolicy policy)
00059 {
00060   _action   = (policy == AcceptAll ? Accept : Reject);
00061   _address  = QHostAddress::Any;
00062   _fromPort = _toPort = 0;
00063   _mask = 0;
00064 }
00065 
00066 /** Constructor. Creates a new policy object based on the given rules. */
00067 Policy::Policy(Action action, QHostAddress addr, uchar mask, 
00068                quint16 fromPort, quint16 toPort)
00069 {
00070   _action   = action;
00071   _address  = addr;
00072   _mask     = mask;
00073   _fromPort = fromPort;
00074   _toPort   = (toPort >= fromPort ? toPort : fromPort);
00075 }
00076 
00077 /** Returns true if this policy is identical to <b>policy</b>. */
00078 bool
00079 Policy::operator==(const Policy &policy) const
00080 {
00081   return ((this->_action   == policy._action)    &&
00082           (this->_address  == policy._address)   &&
00083           (this->_mask     == policy._mask)      &&
00084           (this->_fromPort == policy._fromPort)  &&
00085           (this->_toPort   == policy._toPort));
00086 }
00087 
00088 /** Returns true if this policy matches <b>policy</b>. For example, if this
00089  * policy is "reject *:6660-6669" and <b>policy</b> is "reject *:6662-6664",
00090  * this will return true. For strict comparison, use the == operator. */
00091 bool
00092 Policy::matches(const Policy &policy) const
00093 {
00094   /* This doesn't take into account addr/mask matches yet */
00095   return ((this->_action   == policy._action)    &&
00096           (this->_address  == policy._address)   &&
00097           (this->_mask     == policy._mask)      &&
00098           (this->_fromPort <= policy._fromPort)  &&
00099           (this->_toPort   >= policy._toPort));
00100 }
00101 
00102 /** Parses the given exit policy string. */
00103 void
00104 Policy::fromString(QString policy)
00105 {
00106   /* Separate the action and the address/mask/port info */
00107   QStringList ruleParts = policy.split(" ");
00108   _action = toAction(ruleParts.at(0));
00109   
00110   /* If some address/mask/port stuff was specified, parse it. */
00111   if (ruleParts.size() > 1) {
00112     QStringList addrParts = ruleParts.at(1).split(":");
00113 
00114     /* Parse the address and mask (if specified) */
00115     QString addr = addrParts.at(0);
00116     _address.setAddress(addr.mid(0, addr.indexOf("/")));
00117     if (_address.isNull()) {
00118       _address = QHostAddress::Any;
00119     }
00120     if (addr.contains("/")) {
00121       _mask = addr.mid(addr.indexOf("/")+1).toUInt();
00122     }
00123 
00124     /* Parse the specified port range (if specified) */
00125     if (addrParts.size() > 1) {
00126       QString ports = addrParts.at(1);
00127       _fromPort = ports.mid(0, ports.indexOf("-")).toUInt();
00128       if (ports.contains("-")) {
00129         _toPort = ports.mid(ports.indexOf("-")+1).toUInt();
00130       } else {
00131         _toPort = _fromPort;
00132       }
00133     }
00134   }
00135 }
00136 
00137 /** Converts this policy to a form Tor understands. The format is:
00138  *         "accept|reject ADDR[/MASK][:PORT]"
00139  *
00140  * PORT can be a single port number, an interval of ports "FROM_PORT-TO_PORT",
00141  * or "*". If PORT is omitted, that means "*"
00142  */
00143 QString
00144 Policy::toString() const
00145 {
00146   QString act = (_action == Accept ? "accept" : "reject");
00147   return act + " " + address() + ":" + ports();
00148 }
00149 
00150 /** Converts the given action to a string. This function tolerates both the
00151  * translated and untranslated forms of the string "accept" and "reject". */
00152 Policy::Action
00153 Policy::toAction(QString action)
00154 {
00155   action = action.toLower();
00156   if (action == tr("accept") || action == "accept") {
00157     return Accept;
00158   }
00159   return Reject;
00160 }
00161 
00162 /** Returns the action associated with this policy. NOTE: This string will be
00163  * translated to whatever the current language setting is. */
00164 QString
00165 Policy::action() const
00166 {
00167   return (_action == Accept ? tr("accept") : tr("reject"));
00168 }
00169 
00170 /** Returns the address (and mask, if specified) for this policy. */
00171 QString
00172 Policy::address() const
00173 {
00174   QString addrString;
00175   
00176   if (_mask) {
00177     addrString = _address.toString() + "/" + QString::number(_mask);
00178   } else if (_address == QHostAddress::Any || _address.isNull()) {
00179     addrString = "*";
00180   } else {
00181     addrString = _address.toString();
00182   } 
00183   return addrString;
00184 }
00185 
00186 /** Returns the port (or port range, if specified) for this policy. */
00187 QString
00188 Policy::ports() const
00189 {
00190   QString ports = (_fromPort ? QString::number(_fromPort) : "*");
00191   if (_fromPort && (_toPort > _fromPort)) {
00192     ports += "-" + QString::number(_toPort);
00193   }
00194   return ports;
00195 }
00196 

Generated on Wed Nov 26 21:02:42 2008 for Vidalia by  doxygen 1.5.7.1