Changeset 2959

Show
Ignore:
Timestamp:
08/14/08 06:01:50 (3 months ago)
Author:
borkdomenik
Message:

First commit including the changes according to proposal 121 and the changes of the hidden service authorization protocol.
* changes of the .ui file to imclude basic|stealth check boxes
* include a attribute stealth to the Service entity in order to store the authorization mode
* several changes in the servicepage file according to proposal 121
* several changes in the servicesettings file because of the enlargement of the Service entity
* some smaller bugfixes

Location:
vidalia/branches/hidden-services/src/vidalia/config
Files:
6 modified

Legend:

Unmodified
Added
Removed
  • vidalia/branches/hidden-services/src/vidalia/config/service.cpp

    r2836 r2959  
    1717/** Constructor to create a new Service with initial settings */ 
    1818Service::Service(QString serviceAddress, QString virtualPort, 
    19  QString physicalAddressPort, QString serviceDirectory, bool enabled) 
     19 QString physicalAddressPort, QString serviceDirectory, bool enabled, bool stealth) 
    2020{ 
    2121 
     
    2525  _serviceDirectory = serviceDirectory; 
    2626  _enabled = enabled; 
     27  _stealth = stealth; 
    2728} 
    2829 
     
    3637{ 
    3738  _enabled = enabled; 
     39} 
     40 
     41/** Sets the authorization configuration mode */ 
     42void Service::setStealth(bool stealth) 
     43{ 
     44  _stealth = stealth; 
    3845} 
    3946 
     
    99106  out << myObj.serviceDirectory(); 
    100107  out << myObj.enabled(); 
     108  out << myObj.stealth(); 
    101109  out << myObj.additionalServiceOptions(); 
    102110  out << myObj.users(); 
     
    114122  QString serviceDirectory; 
    115123  bool enabled; 
     124  bool stealth; 
    116125  QString additionalServiceOptions; 
    117126  QList<UserAuthorizationData> users; 
     
    119128  /* Read in from the data stream */ 
    120129  in >> serviceAddress >> virtualPort  >> physicalAddressPort 
    121    >> serviceDirectory >> enabled >> additionalServiceOptions >> users; 
     130   >> serviceDirectory >> enabled >> stealth  
     131   >> additionalServiceOptions >> users; 
    122132 
    123133  /* Set the appropriate class member variables */ 
     
    127137  myObj.setServiceDirectory(serviceDirectory); 
    128138  myObj.setEnabled(enabled); 
     139  myObj.setStealth(stealth); 
    129140  myObj.setAdditionalServiceOptions(additionalServiceOptions); 
    130141  myObj.setUsers(users); 
     
    139150Service::toString() 
    140151{ 
    141   QString s; 
     152  QString s, stealth; 
     153  if(_stealth) { 
     154    stealth = "x1"; 
     155  } 
    142156  s.append(_serviceAddress +"#"+ _virtualPort +"#"+  _physicalAddressPort + 
    143     "#"+ _serviceDirectory +"#"+  _enabled + "#"+ _additionalServiceOptions + 
    144     "#"); 
     157    "#"+ _serviceDirectory +"#"+  _enabled + "#"+ stealth +"#"+  
     158    _additionalServiceOptions + "#"); 
    145159  foreach(UserAuthorizationData user, _users) 
    146160  { 
  • vidalia/branches/hidden-services/src/vidalia/config/service.h

    r2836 r2959  
    2525  /** Constructor to create a new Service with initial settings */ 
    2626  Service(QString serviceAddress, QString virtualPort, 
    27    QString physicalAddressPort, QString serviceDirectory, bool enabled); 
     27   QString physicalAddressPort, QString serviceDirectory, bool enabled, bool stealth); 
    2828  /** Destructor */ 
    2929  virtual ~Service(); 
     
    3838  /** Returns the deployed status of a service */ 
    3939  bool enabled() const { return _enabled; } 
     40  /** Returns the authorization configuration mode */ 
     41  bool stealth() const { return _stealth; } 
    4042  /** Returns the additional options of a service e.g. excludeNodes */ 
    4143  QString additionalServiceOptions() const 
     
    5355  /** Sets the deployed status a service */ 
    5456  void setEnabled(bool enabled); 
     57  /** Sets the authorization configuration mode */ 
     58  void setStealth(bool stealth); 
    5559  /** Sets the additional options of a service e.g. excludeNodes */ 
    5660  void setAdditionalServiceOptions(QString options); 
     
    8185  /** The Enabled status of the service */ 
    8286  bool _enabled; 
     87  /** This attribute represents the configuration mode of the authorization*/ 
     88  bool _stealth; 
    8389  /** Some additional service options, not configured/displayed by Vidalia */ 
    8490  QString _additionalServiceOptions; 
  • vidalia/branches/hidden-services/src/vidalia/config/servicepage.cpp

    r2843 r2959  
    114114  connect(ui.serviceAccessWidget, SIGNAL(itemClicked(QTableWidgetItem*)), this, 
    115115   SLOT(serviceAccessSelectionChanged())); 
     116  connect(ui.checkBox_basic, SIGNAL(toggled(bool)), this, SLOT(checkBoxBasicToggled())); 
     117  connect(ui.checkBox_stealth, SIGNAL(toggled(bool)), this, SLOT(checkBoxStealthToggled())); 
    116118} 
    117119 
     
    141143      bool enabled = _services->value(index).enabled(); 
    142144      QList<UserAuthorizationData> users = _services->value(index).users(); 
     145      bool stealth = _services->value(index).stealth(); 
    143146      Service temp(address, virtualPort, physicalAddress, directoryPath, 
    144        enabled); 
     147       enabled, stealth); 
    145148      temp.setAdditionalServiceOptions(_services->value(ui.serviceWidget-> 
    146149       currentRow()).additionalServiceOptions()); 
     
    287290  QString errmsg = "Error while trying to publish services."; 
    288291  QListIterator<Service> it(services); 
    289   QList<UserAuthorizationData> publishedUsers; 
    290292  bool first = true; 
    291293  while(it.hasNext()) { 
     294    QList<UserAuthorizationData> publishedUsers; 
    292295    Service temp = it.next(); 
    293296    serviceConfString.append("hiddenservicedir=" + 
     
    305308    } 
    306309    if(publishedUsers.size() > 0) { 
     310      QString stealthMode = "basic"; 
     311      if(temp.stealth()) { 
     312        stealthMode = "stealth"; 
     313      } 
    307314      serviceConfString.append(" hiddenserviceversion=\"2\" \ 
    308        hiddenserviceauthorizeclient="+ 
    309        string_escape(createUserAuthStringForTor(publishedUsers))); 
     315       hiddenserviceauthorizeclient="+string_escape(stealthMode+" " +  
     316       createUserAuthStringForTor(publishedUsers))); 
    310317    } 
    311318    serviceConfString.append(" "+ temp.additionalServiceOptions()); 
    312319  } 
     320  VMessageBox::warning(this, tr("torConfString"), serviceConfString, 
     321     VMessageBox::Ok); 
    313322  _serviceSettings->applyServices(serviceConfString, &errmsg); 
    314323} 
     
    371380  QString torConfigurationString = _serviceSettings-> 
    372381   getHiddenServiceDirectories(); 
     382   VMessageBox::warning(this, tr("kompletter string:"), torConfigurationString, 
     383             VMessageBox::Ok); 
    373384  torServiceList = extractSingleServices(torConfigurationString); 
    374385  // the services stored with vidalia 
     
    410421/** this method returns a Service by parseing the configuration string 
    411422 *  of Tor and storing its values into the object */ 
     423 //XTODO hier den parser auch anpassen um basic/stealth abzufange!! 
    412424Service 
    413425ServicePage::generateService(QString s) 
     
    440452       additionalOptions.remove(indexstart, (indexend-indexstart)); 
    441453     } 
     454    //remove first appearance of HiddenServiceVerison 
     455    indexstart = additionalOptions.indexOf("hiddenserviceversion", 0, Qt::CaseInsensitive); 
     456    endindex = additionalOptions.indexOf("250", indexstart); 
     457    if(endindex != -1) { 
     458      additionalOptions.remove(indexstart, (endindex-indexstart)+4); 
     459    } else { 
     460      endindex = additionalOptions.indexOf("\n", indexstart); 
     461      if(endindex != -1) { 
     462        additionalOptions.remove(indexstart, (endindex-indexstart)); 
     463      } else { 
     464        endindex = additionalOptions.length()-1; 
     465        additionalOptions.remove(indexstart, (endindex-indexstart)); 
     466      } 
     467    } 
    442468    //remove all appearances of "250" 
    443469    while(additionalOptions.contains("250")) { 
     
    464490 
    465491  QString address, virtualPort, physAddressPort, serviceDir; 
     492  bool stealth = false; 
    466493  // service directory 
    467494  QStringList strList = s.split("\n"); 
     
    485512       virtualPort = tempVirtualPort.remove(0, 1); 
    486513  } 
    487   //get all users that are in the client-keys file 
    488   QList<UserAuthorizationData> allUsers = parseClientKeys(serviceDir); 
    489   //get all actual users by parsing the hostname file 
    490514  QList<UserAuthorizationData> actualUsers; 
    491515  if(s.contains("HiddenServiceAuthorizeClient")) { 
     
    495519    QStringList strList6 = strList5.first().split("\n"); 
    496520    strList6.first().remove(0,1); 
     521    QStringList stealthList = strList6.first().split(" "); 
     522    if(stealthList.first().compare("stealth") == 0) { 
     523      stealth = true; 
     524      strList6.first().remove(0,8); 
     525    } else { 
     526      strList6.first().remove(0,6); 
     527    } 
    497528    QStringList userList = strList6.first().split(","); 
    498529    foreach(QString user, userList) { 
    499530      QString authdata, filereader; 
    500531      int index = 0; 
    501       //remove the users in the allUsers data structure,if they are actual users 
    502       while(index < allUsers.size()) { 
    503         UserAuthorizationData temp = allUsers.at(index); 
    504         if(temp.identification().compare(user) == 0) { 
    505           allUsers.removeAt(index); 
    506         } 
    507         index++; 
    508       } 
    509532      //parse the hostname file to get the authorization data 
    510533      QString dir = serviceDir; 
     
    520543        } 
    521544        QStringList strList7 = filereader.split("\n"); 
    522         //remove first 5 lines 
    523         for(int i = 0; i < 5; i++) { 
    524           strList7.removeFirst(); 
    525         } 
    526         while(strList7.isEmpty() == false) { 
    527           QString temp = strList7.first(); 
    528           if(temp.contains(""+user)){ 
    529             break; 
    530           } else { 
    531              strList7.removeFirst(); 
    532           } 
    533         } 
    534         QString temp = strList7.first(); 
    535         QStringList strList8 = temp.split("#"); 
    536         authdata = strList8.first(); 
    537         authdata.remove(authdata.length()-1,1); 
    538       } 
    539       UserAuthorizationData u(authdata, user); 
    540       actualUsers.push_back(u); 
    541     } 
    542   } 
    543   //if there are some users not in the actual users data structure, 
    544   //but in client-keys 
    545   if(allUsers.size() > 0) { 
    546     QListIterator<UserAuthorizationData> it2(allUsers); 
    547     while(it2.hasNext()) { 
    548       UserAuthorizationData tempData = it2.next(); 
    549       actualUsers.push_back(tempData); 
    550     } 
    551   } 
    552   //get .onion address 
     545        foreach(QString userString, strList7) { 
     546         if(userString.length() > 1 && userString.contains(user)) { 
     547           QString onion, cookie, id; 
     548           QStringList strList2 = userString.split(" "); 
     549           onion = strList2.first(); 
     550           strList2.removeFirst(); 
     551           cookie = strList2.first(); 
     552           strList2.removeFirst(); 
     553           strList2.removeFirst(); 
     554           strList2.removeFirst(); 
     555           id = strList2.first(); 
     556           authdata = onion+" "+cookie; 
     557           UserAuthorizationData u(onion+" "+cookie, id); 
     558           u.setEnabled(true); 
     559           actualUsers.push_back(u); 
     560         } 
     561       } 
     562      } 
     563    } 
     564  } 
     565  //get .onion address, cookie and identification 
    553566  if(userAuthConfigured == true) { 
    554567    address = "[Client Auth Configured]"; 
     
    569582        } 
    570583  } 
    571   Service service(address, virtualPort, physAddressPort, serviceDir, true); 
     584  Service service(address, virtualPort, physAddressPort, serviceDir, true, stealth); 
    572585  service.setAdditionalServiceOptions(additionalOptions); 
    573586  service.setUsers(actualUsers); 
     
    579592 *  get all users that had a authorization for the Service 
    580593 * @return a list of all users found in client_keys*/ 
    581 QList<UserAuthorizationData> 
    582 ServicePage::parseClientKeys(QString dir) 
    583 { 
    584   QList<UserAuthorizationData> result; 
    585   QString value; 
    586   QFile file(dir.append("/client_keys")); 
    587   if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { 
    588     return result; 
    589   } else { 
    590       QTextStream in(&file); 
    591       QString content; 
    592       while (!in.atEnd()) { 
    593         content.append(in.readLine()); 
    594         content.append("\n"); 
    595       } 
    596       value = content; 
    597   } 
    598   QStringList strList = value.split("client-name"); 
    599   strList.removeFirst(); 
    600   foreach(QString user, strList) { 
    601     QStringList strList2 = user.split("\n"); 
    602     UserAuthorizationData u("[Created by Tor]", strList2.first().trimmed()); 
    603     u.setEnabled(false); 
    604     result.push_back(u); 
    605   } 
    606   return result; 
    607 } 
     594//QList<UserAuthorizationData> 
     595//ServicePage::parseClientKeys(QString dir) 
     596//{ 
     597  //QList<UserAuthorizationData> result; 
     598  //QString value; 
     599  //XTODO hier änderungen!! 
     600  //QFile file(dir.append("/hostname")); 
     601  //if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { 
     602    //return result; 
     603  //} else { 
     604      //QTextStream in(&file); 
     605      //QString content; 
     606      //while (!in.atEnd()) { 
     607        //content.append(in.readLine()); 
     608        //content.append("\n"); 
     609      //} 
     610      //value = content; 
     611  //} 
     612  //QStringList strList1 = value.split("\n"); 
     613  //foreach(QString user, strList1) { 
     614   //if(user.length() > 1) { 
     615     //QString onion, cookie, id; 
     616     //QStringList strList2 = user.split(" "); 
     617     //onion = strList2.first(); 
     618     //strList2.removeFirst(); 
     619     //cookie = strList2.first(); 
     620     //strList2.removeFirst(); 
     621     //strList2.removeFirst(); 
     622     //strList2.removeFirst(); 
     623     //id = strList2.first(); 
     624     //UserAuthorizationData u(onion+" "+cookie, id); 
     625     //u.setEnabled(false); 
     626     //result.push_back(u); 
     627   //} 
     628 //} 
     629  //return result; 
     630//} 
    608631 
    609632/** this method merges the list of services received from Vidalia and Tor 
     
    763786  Service s; 
    764787  s.setEnabled(true); 
     788  s.setStealth(false); 
    765789  _services->insert(rows, s); 
    766790} 
     
    9761000    ui.restrictAccessCheckBox->setCheckState(Qt::Unchecked); 
    9771001  } else { 
     1002      if(selService.stealth()) { 
     1003        ui.checkBox_stealth->setCheckState(Qt::Checked); 
     1004        ui.checkBox_basic->setCheckState(Qt::Unchecked); 
     1005      } else { 
     1006        ui.checkBox_basic->setCheckState(Qt::Checked); 
     1007        ui.checkBox_stealth->setCheckState(Qt::Unchecked); 
     1008      } 
    9781009      int rowcount = 0; 
    9791010      QListIterator<UserAuthorizationData> it(assoziatedUsers); 
     
    11941225  QString serviceAuthdata, serviceIdentification; 
    11951226  serviceAuthdata = ui.authLineAccess->text(); 
    1196   serviceIdentification = ui.commentLineAccess->text(); 
    1197   if(serviceAuthdata.length() == 0 || serviceIdentification.length() == 0) { 
    1198     VMessageBox::warning(this, tr("Error"), tr("Please fill out both fields."), 
     1227  serviceIdentification = ""+ui.commentLineAccess->text(); 
     1228  if(serviceAuthdata.length() == 0) { 
     1229    VMessageBox::warning(this, tr("Error"), tr("Authorization data has to be set."), 
    11991230     VMessageBox::Ok); 
    12001231     return; 
    12011232  } else { 
    1202     for(int i = 0; i < ui.serviceAccessWidget->rowCount(); i++) { 
    1203       QString tempidentification = ui.serviceAccessWidget->item(i, 1)->text(); 
    1204       if(serviceIdentification.compare(tempidentification) == 0) { 
    1205         VMessageBox::warning(this, tr("Error"), tr("Identification has to be\ 
    1206         unique, try another one please."), VMessageBox::Ok); 
    1207         ui.commentLineAccess->clear(); 
    1208         return; 
    1209      } 
    1210     } 
    12111233    int pos = 0; 
    1212     if(_identificationValidator->validate(serviceIdentification, pos) == 
    1213      QValidator::Acceptable) { 
    12141234      if(validateServiceAuth(serviceAuthdata) == QValidator::Acceptable) { 
    12151235        int rows = ui.serviceAccessWidget->rowCount(); 
     
    12261246        ServiceAuthorizationData s(serviceAuthdata, serviceIdentification); 
    12271247        _consumedServices->insert(serviceIdentification, s); 
    1228       } 
    1229     } else { 
    1230       VMessageBox::warning(this, tr("Error"), tr("Invalid characters for the\ 
    1231        identification, only {[a-z][A-Z][0-9]+-_} allowed. The length has to be\ 
    1232        between 1 and 19."), VMessageBox::Ok); 
    1233         ui.commentLineAccess->clear(); 
    1234         return; 
    1235     } 
     1248      } else { 
     1249         VMessageBox::warning(this, tr("Error"), tr("Invalid input for the\ 
     1250          authorization. Only [onion-Address] [descriptor-cookie] allowed."), 
     1251          VMessageBox::Ok); 
     1252      } 
    12361253  } 
    12371254} 
     
    12431260ServicePage::validateServiceAuth(QString authString) 
    12441261{ 
     1262  if(authString.length() != 45 || authString.contains(" ") == false) { 
     1263    return QValidator::Invalid; 
     1264  } 
    12451265  QStringList strList = authString.split(" "); 
    12461266  int pos = 0; 
     
    15041524} 
    15051525 
     1526void 
     1527ServicePage::checkBoxBasicToggled() 
     1528{ 
     1529  bool state = ui.checkBox_basic->checkState() == Qt::Checked; 
     1530  if(state) { 
     1531    ui.checkBox_stealth->setCheckState(Qt::Unchecked); 
     1532  } else { 
     1533    ui.checkBox_stealth->setCheckState(Qt::Checked); 
     1534  } 
     1535  Service s = _services->take(ui.serviceWidget->currentRow()); 
     1536  s.setStealth(!state); 
     1537  _services->insert(ui.serviceWidget->currentRow(), s); 
     1538} 
     1539 
     1540void 
     1541ServicePage::checkBoxStealthToggled() 
     1542{ 
     1543  bool state = ui.checkBox_stealth->checkState() == Qt::Checked; 
     1544  if(state) { 
     1545    ui.checkBox_basic->setCheckState(Qt::Unchecked); 
     1546  } else { 
     1547    ui.checkBox_basic->setCheckState(Qt::Checked); 
     1548  } 
     1549  Service s = _services->take(ui.serviceWidget->currentRow()); 
     1550  s.setStealth(state); 
     1551  _services->insert(ui.serviceWidget->currentRow(), s); 
     1552} 
     1553 
  • vidalia/branches/hidden-services/src/vidalia/config/servicepage.h

    r2836 r2959  
    5454  * get all users that had a authorization for the Service 
    5555  * @return a list of all users found in client_keys*/ 
    56   QList<UserAuthorizationData> parseClientKeys(QString dir); 
     56  //QList<UserAuthorizationData> parseClientKeys(QString dir); 
    5757  /** this method creates the configuration string for tor including the 
    5858   * user authorization*/ 
     
    114114   * entry(Provided Services)*/ 
    115115  void serviceAuthSelectionChanged(); 
     116  void checkBoxBasicToggled(); 
     117  void checkBoxStealthToggled(); 
    116118 
    117119private: 
  • vidalia/branches/hidden-services/src/vidalia/config/servicepage.ui

    r2836 r2959  
    77    <y>0</y> 
    88    <width>653</width> 
    9     <height>519</height> 
     9    <height>496</height> 
    1010   </rect> 
    1111  </property> 
     
    2525   <iconset>../../../../../.designer/backup</iconset> 
    2626  </property> 
    27   <layout class="QVBoxLayout" > 
    28    <item> 
     27  <layout class="QGridLayout" > 
     28   <item row="0" column="0" > 
    2929    <widget class="QTabWidget" name="tabWidget" > 
    3030     <property name="sizePolicy" > 
     
    4141       <string>Provide Hidden Services</string> 
    4242      </attribute> 
    43       <layout class="QVBoxLayout" > 
    44        <item> 
    45         <widget class="QGroupBox" name="groupBox" > 
    46          <property name="sizePolicy" > 
    47           <sizepolicy vsizetype="Fixed" hsizetype="Minimum" > 
    48            <horstretch>0</horstretch> 
    49            <verstretch>0</verstretch> 
    50           </sizepolicy> 
    51          </property> 
    52          <property name="minimumSize" > 
    53           <size> 
    54            <width>0</width> 
    55            <height>0</height> 
    56           </size> 
    57          </property> 
    58          <property name="maximumSize" > 
    59           <size> 
    60            <width>16777215</width> 
    61            <height>16777215</height> 
    62           </size> 
    63          </property> 
    64          <property name="title" > 
    65           <string>Service List</string> 
    66          </property> 
     43      <widget class="QGroupBox" name="groupBox" > 
     44       <property name="geometry" > 
     45        <rect> 
     46         <x>9</x> 
     47         <y>7</y> 
     48         <width>613</width> 
     49         <height>230</height> 
     50        </rect> 
     51       </property> 
     52       <property name="sizePolicy" > 
     53        <sizepolicy vsizetype="Fixed" hsizetype="Minimum" > 
     54         <horstretch>0</horstretch> 
     55         <verstretch>0</verstretch> 
     56        </sizepolicy> 
     57       </property> 
     58       <property name="minimumSize" > 
     59        <size> 
     60         <width>561</width> 
     61         <height>230</height> 
     62        </size> 
     63       </property> 
     64       <property name="maximumSize" > 
     65        <size> 
     66         <width>16777215</width> 
     67         <height>16777215</height> 
     68        </size> 
     69       </property> 
     70       <property name="title" > 
     71        <string>Service List</string> 
     72       </property> 
     73       <widget class="QWidget" name="layoutWidget" > 
     74        <property name="geometry" > 
     75         <rect> 
     76          <x>11</x> 
     77          <y>29</y> 
     78          <width>591</width> 
     79          <height>190</height> 
     80         </rect> 
     81        </property> 
     82        <layout class="QGridLayout" > 
     83         <item rowspan="5" row="0" column="0" > 
     84          <widget class="QTableWidget" name="serviceWidget" > 
     85           <property name="sizePolicy" > 
     86            <sizepolicy vsizetype="Preferred" hsizetype="Expanding" > 
     87             <horstretch>0</horstretch> 
     88             <verstretch>0</verstretch> 
     89            </sizepolicy> 
     90           </property> 
     91           <property name="minimumSize" > 
     92            <size> 
     93             <width>0</width> 
     94             <height>0</height> 
     95            </size> 
     96           </property> 
     97           <property name="maximumSize" > 
     98            <size> 
     99             <width>16777215</width> 
     100             <height>16777215</height> 
     101            </size> 
     102           </property> 
     103           <property name="baseSize" > 
     104            <size> 
     105             <width>0</width> 
     106             <height>0</height> 
     107            </size> 
     108           </property> 
     109           <property name="selectionMode" > 
     110            <enum>QAbstractItemView::SingleSelection</enum> 
     111           </property> 
     112           <property name="selectionBehavior" > 
     113            <enum>QAbstractItemView::SelectRows</enum> 
     114           </property> 
     115           <property name="textElideMode" > 
     116            <enum>Qt::ElideLeft</enum> 
     117           </property> 
     118           <property name="showGrid" > 
     119            <bool>true</bool> 
     120           </property> 
     121           <column> 
     122            <property name="text" > 
     123             <string>Onion Address</string> 
     124            </property> 
     125           </column> 
     126           <column> 
     127            <property name="text" > 
     128             <string>Virtual Port</string> 
     129            </property> 
     130           </column> 
     131           <column> 
     132            <property name="text" > 
     133             <string>Target</string> 
     134            </property> 
     135           </column> 
     136           <column> 
     137            <property name="text" > 
     138             <string>Directory Path</string> 
     139            </property> 
     140           </column> 
     141           <column> 
     142            <property name="text" > 
     143             <string>Enabled</string> 
     144            </property> 
     145           </column> 
     146          </widget> 
     147         </item> 
     148         <item row="0" column="1" > 
     149          <widget class="QToolButton" name="addServiceBtn" > 
     150           <property name="sizePolicy" > 
     151            <sizepolicy vsizetype="Fixed" hsizetype="Fixed" > 
     152             <horstretch>0</horstretch> 
     153             <verstretch>0</verstretch>