[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[vidalia-svn] r2836: First Prototyp of my Google Summer of Code Project. Containi (in vidalia/branches/hidden-services/src/vidalia: . config)



Author: borkdomenik
Date: 2008-07-06 08:03:36 -0400 (Sun, 06 Jul 2008)
New Revision: 2836

Added:
   vidalia/branches/hidden-services/src/vidalia/config/abstractauthorizationdata.cpp
   vidalia/branches/hidden-services/src/vidalia/config/abstractauthorizationdata.h
   vidalia/branches/hidden-services/src/vidalia/config/serviceauthorizationdata.cpp
   vidalia/branches/hidden-services/src/vidalia/config/serviceauthorizationdata.h
   vidalia/branches/hidden-services/src/vidalia/config/userauthorizationdata.cpp
   vidalia/branches/hidden-services/src/vidalia/config/userauthorizationdata.h
Removed:
   vidalia/branches/hidden-services/src/vidalia/config/user.cpp
   vidalia/branches/hidden-services/src/vidalia/config/user.h
Modified:
   vidalia/branches/hidden-services/src/vidalia/CMakeLists.txt
   vidalia/branches/hidden-services/src/vidalia/config/service.cpp
   vidalia/branches/hidden-services/src/vidalia/config/service.h
   vidalia/branches/hidden-services/src/vidalia/config/servicepage.cpp
   vidalia/branches/hidden-services/src/vidalia/config/servicepage.h
   vidalia/branches/hidden-services/src/vidalia/config/servicepage.ui
   vidalia/branches/hidden-services/src/vidalia/config/servicesettings.cpp
   vidalia/branches/hidden-services/src/vidalia/config/servicesettings.h
Log:
First Prototyp of my Google Summer of Code Project. Containing:
* new entities(AbstractAuthorizationData, UserAuthorizationData, ServiceAuthorizationData)
* persistent storage of Service Authorization for Hidden Services
* persistent storage of Client Authorization for Hidden Services
* enlarge the ui to display the authorization data for cient and service auth
* Validation of identifiers
* Validation of cookie
* Validation of onion-address
* Communication to Tor-Controller for Client Authorization (option="HidServAuthorizeClient")
* Communication to Tor for Consumed Hidden Services (option="HidServAuth")
* changed label "comment" to "identification" (hint of edmanm)
* several bugfixes

Modified: vidalia/branches/hidden-services/src/vidalia/CMakeLists.txt
===================================================================
--- vidalia/branches/hidden-services/src/vidalia/CMakeLists.txt	2008-07-04 15:16:43 UTC (rev 2835)
+++ vidalia/branches/hidden-services/src/vidalia/CMakeLists.txt	2008-07-06 12:03:36 UTC (rev 2836)
@@ -49,6 +49,7 @@
 
 ## Configuration dialog sources
 set(vidalia_SRCS ${vidalia_SRCS}
+  config/abstractauthorizationdata.cpp
   config/abstracttorsettings.cpp
   config/advancedpage.cpp
   config/appearancepage.cpp
@@ -66,11 +67,12 @@
   config/serverpage.cpp
   config/serversettings.cpp
   config/service.cpp
+  config/serviceauthorizationdata.cpp
   config/servicelist.cpp
   config/servicepage.cpp
   config/servicesettings.cpp
   config/torsettings.cpp
-  config/user.cpp
+  config/userauthorizationdata.cpp
   config/vidaliasettings.cpp
   config/vsettings.cpp
 )
@@ -90,6 +92,7 @@
   config/serverpage.h
   config/serversettings.h
   config/servicepage.h
+  config/servicesettings.h
   config/torsettings.h
   config/vidaliasettings.h
   config/vsettings.h

Added: vidalia/branches/hidden-services/src/vidalia/config/abstractauthorizationdata.cpp
===================================================================
--- vidalia/branches/hidden-services/src/vidalia/config/abstractauthorizationdata.cpp	                        (rev 0)
+++ vidalia/branches/hidden-services/src/vidalia/config/abstractauthorizationdata.cpp	2008-07-06 12:03:36 UTC (rev 2836)
@@ -0,0 +1,68 @@
+/*
+**  This file is part of Vidalia, and is subject to the license terms in the
+**  LICENSE file, found in the top level directory of this distribution. If you
+**  did not receive the LICENSE file with this file, you may obtain it from the
+**  Vidalia source package distributed by the Vidalia Project at
+**  http://www.vidalia-project.net/. No part of Vidalia, including this file,
+**  may be copied, modified, propagated, or distributed except according to the
+**  terms described in the LICENSE file.
+*/
+
+#include "abstractauthorizationdata.h"
+AbstractAuthorizationData::AbstractAuthorizationData()
+{
+}
+
+/** Constructor. */
+AbstractAuthorizationData::AbstractAuthorizationData(QString authdata,
+ QString identification)
+{
+  _authdata = authdata;
+  _identification = identification;
+}
+
+/* Sets the comment */
+void AbstractAuthorizationData::setIdentification(QString identification)
+{
+  _identification = identification;
+}
+
+/** Sets the authorization data */
+void AbstractAuthorizationData::setAuthdata(QString authdata)
+{
+  _authdata = authdata;
+}
+
+/** Writes service class data from <b>myObj</b> to the QDataStream
+ * <b>out</b>. */
+QDataStream& operator<<(QDataStream &out, const
+ AbstractAuthorizationData &myObj)
+{
+  out << myObj.identification() << myObj.authdata();
+  return out;
+}
+
+/** Reads service class data in from the QDataStream <b>in</b> and
+ populates * the <b>myObj</b> object accordingly. */
+QDataStream& operator>>(QDataStream &in, AbstractAuthorizationData &myObj)
+{
+  QString identification;
+  QString authdata;
+  /* Read in from the data stream */
+  in >> identification >> authdata;
+  /* Set the appropriate class member variables */
+  myObj.setIdentification(identification);
+  myObj.setAuthdata(authdata);
+  /* Return the updated data stream */
+  return in;
+}
+
+/** this method creates a string by concatenating the values of the service */
+QString
+AbstractAuthorizationData::toString()
+{
+  QString result;
+  result.append(_authdata+"*"+_identification+"#");
+  return result;
+}
+

Added: vidalia/branches/hidden-services/src/vidalia/config/abstractauthorizationdata.h
===================================================================
--- vidalia/branches/hidden-services/src/vidalia/config/abstractauthorizationdata.h	                        (rev 0)
+++ vidalia/branches/hidden-services/src/vidalia/config/abstractauthorizationdata.h	2008-07-06 12:03:36 UTC (rev 2836)
@@ -0,0 +1,52 @@
+/*
+**  This file is part of Vidalia, and is subject to the license terms in the
+**  LICENSE file, found in the top level directory of this distribution. If you
+**  did not receive the LICENSE file with this file, you may obtain it from the
+**  Vidalia source package distributed by the Vidalia Project at
+**  http://www.vidalia-project.net/. No part of Vidalia, including this file,
+**  may be copied, modified, propagated, or distributed except according to the
+**  terms described in the LICENSE file.
+*/
+
+#ifndef ABSTRACTAUTHORIZATIONDATA_H_
+#define ABSTRACTAUTHORIZATIONDATA_H_
+
+#include <QString>
+#include <QMetaType>
+
+class AbstractAuthorizationData
+{
+public:
+
+  AbstractAuthorizationData();
+  /** Constructor. */
+  AbstractAuthorizationData(QString authdata, QString identification);
+  /** Returns the comment of a specific user */
+  QString identification() const { return _identification; }
+  /** Returns the authorization data of a specific user */
+  QString authdata() const { return _authdata; }
+  /** Sets a comment of a specific user */
+  void setIdentification(QString identification);
+  /** Sets the authorization data of a specific user */
+  void setAuthdata(QString authdata);
+  /** Writes service class data from <b>myObj</b> to the QDataStream
+  * <b>out</b>. */
+  friend QDataStream&operator<<(QDataStream &out, const
+   AbstractAuthorizationData &myObj);
+  /** Reads service class data in from the QDataStream <b>in</b> and
+  populates * the <b>myObj</b> object accordingly. */
+  friend QDataStream&operator>>(QDataStream &in,
+   AbstractAuthorizationData &myObj);
+  /** this method creates a string by concatenating the values of the service*/
+  QString toString();
+
+private:
+  /** The comment of a specific user */
+  QString _identification;
+  /** The authorization data of a specific user */
+  QString _authdata;
+
+};
+Q_DECLARE_METATYPE(AbstractAuthorizationData);
+#endif /*AbstractAuthorizationData_H_*/
+

Modified: vidalia/branches/hidden-services/src/vidalia/config/service.cpp
===================================================================
--- vidalia/branches/hidden-services/src/vidalia/config/service.cpp	2008-07-04 15:16:43 UTC (rev 2835)
+++ vidalia/branches/hidden-services/src/vidalia/config/service.cpp	2008-07-06 12:03:36 UTC (rev 2836)
@@ -67,16 +67,28 @@
   _additionalServiceOptions = options;
 }
 
-void Service::addUser(User user)
+void Service::addUser(UserAuthorizationData user)
 {
   _users.push_back(user);
 }
 
-void Service::setUsers(QList<User> users)
+void Service::setUsers(QList<UserAuthorizationData> users)
 {
   _users = users;
 }
 
+bool Service::isMember(UserAuthorizationData user)
+{
+  QListIterator<UserAuthorizationData> it(_users);
+  while(it.hasNext()) {
+    UserAuthorizationData temp = it.next();
+    if(temp.identification().compare(user.identification()) == 0) {
+      return true;
+    }
+  }
+  return false;
+}
+
 /** Writes service class data from <b>myObj</b> to the QDataStream
  * <b>out</b>. */
 QDataStream&operator<<(QDataStream &out, const Service &myObj)
@@ -102,7 +114,7 @@
   QString serviceDirectory;
   bool enabled;
   QString additionalServiceOptions;
-  QList<User> users;
+  QList<UserAuthorizationData> users;
 
   /* Read in from the data stream */
   in >> serviceAddress >> virtualPort  >> physicalAddressPort
@@ -116,7 +128,7 @@
   myObj.setEnabled(enabled);
   myObj.setAdditionalServiceOptions(additionalServiceOptions);
   myObj.setUsers(users);
-  
+
   /* Return the updated data stream */
   return in;
 }
@@ -130,9 +142,10 @@
   s.append(_serviceAddress +"#"+ _virtualPort +"#"+  _physicalAddressPort +
     "#"+ _serviceDirectory +"#"+  _enabled + "#"+ _additionalServiceOptions +
     "#");
-  foreach(User user, _users)
+  foreach(UserAuthorizationData user, _users)
   {
     s.append(user.toString());
   }
   return s;
 }
+

Modified: vidalia/branches/hidden-services/src/vidalia/config/service.h
===================================================================
--- vidalia/branches/hidden-services/src/vidalia/config/service.h	2008-07-04 15:16:43 UTC (rev 2835)
+++ vidalia/branches/hidden-services/src/vidalia/config/service.h	2008-07-06 12:03:36 UTC (rev 2836)
@@ -11,7 +11,7 @@
 #ifndef SERVICE_H_
 #define SERVICE_H_
 
-#include <user.h>
+#include <userauthorizationdata.h>
 #include <QString>
 #include <QList>
 #include <QMetaType>
@@ -41,7 +41,7 @@
   QString additionalServiceOptions() const
    { return _additionalServiceOptions; }
   /** Returns the list of users associated to the service */
-  QList<User> users() const { return _users; }
+  QList<UserAuthorizationData> users() const { return _users; }
   /** Sets the adress of a service */
   void setServiceAddress(QString serviceAddress);
   /** Sets the listening port of a service */
@@ -55,16 +55,18 @@
   /** Sets the additional options of a service e.g. excludeNodes */
   void setAdditionalServiceOptions(QString options);
   /** Adds the given user to the list of users associated to the service */
-  void addUser(User user);
+  void addUser(UserAuthorizationData user);
   /** Sets the list of users as the associated users to the service */
-  void setUsers(QList<User> users);
+  void setUsers(QList<UserAuthorizationData> users);
+  /** returns true if the given users is in the list of users */
+  bool isMember(UserAuthorizationData user);
   /** Writes service class data from <b>myObj</b> to the QDataStream
   * <b>out</b>. */
   friend QDataStream& operator<<(QDataStream &out, const Service &myObj);
   /** Reads service class data in from the QDataStream <b>in</b> and
   populates * the <b>myObj</b> object accordingly. */
   friend QDataStream& operator>>(QDataStream &in, Service &myObj);
-  /** this method creates a string by concatenating the values of the service */
+  /** this method creates a string by concatenating the values of the service*/
   QString toString();
 
 private:
@@ -81,7 +83,7 @@
   /** Some additional service options, not configured/displayed by Vidalia */
   QString _additionalServiceOptions;
   /** The list of users associated to the service */
-  QList<User> _users;
+  QList<UserAuthorizationData> _users;
 
 };
 Q_DECLARE_METATYPE(Service);

Added: vidalia/branches/hidden-services/src/vidalia/config/serviceauthorizationdata.cpp
===================================================================
--- vidalia/branches/hidden-services/src/vidalia/config/serviceauthorizationdata.cpp	                        (rev 0)
+++ vidalia/branches/hidden-services/src/vidalia/config/serviceauthorizationdata.cpp	2008-07-06 12:03:36 UTC (rev 2836)
@@ -0,0 +1,23 @@
+/*
+**  This file is part of Vidalia, and is subject to the license terms in the
+**  LICENSE file, found in the top level directory of this distribution. If you
+**  did not receive the LICENSE file with this file, you may obtain it from the
+**  Vidalia source package distributed by the Vidalia Project at
+**  http://www.vidalia-project.net/. No part of Vidalia, including this file,
+**  may be copied, modified, propagated, or distributed except according to the
+**  terms described in the LICENSE file.
+*/
+
+#include "serviceauthorizationdata.h"
+
+ServiceAuthorizationData::ServiceAuthorizationData()
+{
+}
+
+/** Constructor to create a new User with initial settings */
+ServiceAuthorizationData::ServiceAuthorizationData(QString authdata,
+ QString identification):
+ AbstractAuthorizationData(authdata, identification)
+{
+}
+

Added: vidalia/branches/hidden-services/src/vidalia/config/serviceauthorizationdata.h
===================================================================
--- vidalia/branches/hidden-services/src/vidalia/config/serviceauthorizationdata.h	                        (rev 0)
+++ vidalia/branches/hidden-services/src/vidalia/config/serviceauthorizationdata.h	2008-07-06 12:03:36 UTC (rev 2836)
@@ -0,0 +1,31 @@
+/*
+**  This file is part of Vidalia, and is subject to the license terms in the
+**  LICENSE file, found in the top level directory of this distribution. If you
+**  did not receive the LICENSE file with this file, you may obtain it from the
+**  Vidalia source package distributed by the Vidalia Project at
+**  http://www.vidalia-project.net/. No part of Vidalia, including this file,
+**  may be copied, modified, propagated, or distributed except according to the
+**  terms described in the LICENSE file.
+*/
+
+#ifndef SERVICEAUTHORIZATIONDATA_H_
+#define SERVICEAUTHORIZATIONDATA_H_
+
+#include <QString>
+#include <QMetaType>
+
+#include "abstractauthorizationdata.h"
+
+class ServiceAuthorizationData : public AbstractAuthorizationData
+
+{
+public:
+
+  ServiceAuthorizationData();
+  /** Constructor to create a new Service with initial settings */
+  ServiceAuthorizationData(QString authdata, QString identification);
+
+};
+Q_DECLARE_METATYPE(ServiceAuthorizationData);
+#endif /*ServiceAuthorizationData_H_*/
+

Modified: vidalia/branches/hidden-services/src/vidalia/config/servicepage.cpp
===================================================================
--- vidalia/branches/hidden-services/src/vidalia/config/servicepage.cpp	2008-07-04 15:16:43 UTC (rev 2835)
+++ vidalia/branches/hidden-services/src/vidalia/config/servicepage.cpp	2008-07-06 12:03:36 UTC (rev 2836)
@@ -15,35 +15,45 @@
 #include <QFile>
 #include <QTextStream>
 #include <file.h>
+
 #include "configdialog.h"
 #include "ipvalidator.h"
-#include "user.h"
+#include "userauthorizationdata.h"
 #include "service.h"
+#include "serviceauthorizationdata.h"
 #include "servicelist.h"
+#include "servicepage.h"
 #include "domainvalidator.h"
-#include "ipvalidator.h"
 
-//TODO aufpassen das keine '#' im comment sein dürfen und auch nicht in der authdata!
-
 /** Constructor */
 ServicePage::ServicePage(QWidget *parent)
 : ConfigPage(parent, tr("Services"))
 {
   /* Invoke the Qt Designer generated object setup routine */
   ui.setupUi(this);
-  /* Keep a pointer to the TorControl object used to talk to Tor */
-  _torControl = Vidalia::torControl();
-  /* Create Tor settings objects */
-  _torSettings = new TorSettings;
   /* Keep a pointer to the ServiceSettings object used to store
    * the configuration */
-  _serviceSettings = new ServiceSettings(_torControl);
+  _serviceSettings = new ServiceSettings(Vidalia::torControl());
   /* A QMap, mapping from the row number to the Entity for
    * all services */
   _services = new QMap<int, Service>();
   /* A QMap, mapping from the directory path to the Entity for
    * all Tor services */
   _torServices = new QMap<QString, Service>();
+  /* a map mapping from the unique identification, to the auth data
+   * of a service*/
+  _consumedServices = new QMap<QString, ServiceAuthorizationData>();
+  /** A QRegExpValidator to validate the identification of client auth(Id)
+   * and service auth(Id)*/
+  QRegExp rx("[a-zA-Z0-9\\+\\-\\_]{0,18}([a-zA-Z0-9\\+\\-\\_])");
+  _identificationValidator = new QRegExpValidator(rx, this);
+  /** A QRegExpValidator to validate a onion address (base32,
+   * 16 chars +".onion"*/
+  QRegExp base32("[a-z2-7]{15}([a-z2-7]).onion");
+  _onionAdressValidator = new QRegExpValidator(base32, this);
+  /** A QRegExpValidator to validate a cookie(base64, 22 chars)*/
+  QRegExp base64("[a-zA-Z0-9\\+\\-\\/]{21}([a-zA-Z0-9\\+\\-\\/])");
+  _cookieValidator = new QRegExpValidator(base64, this);
 
   ui.serviceWidget->horizontalHeader()->resizeSection(0, 150);
   ui.serviceWidget->horizontalHeader()->resizeSection(1, 89);
@@ -55,17 +65,30 @@
   ui.serviceWidget->horizontalHeader()->setResizeMode(2, QHeaderView::Stretch);
   ui.serviceWidget->horizontalHeader()->setResizeMode(3, QHeaderView::Stretch);
   ui.serviceWidget->verticalHeader()->hide();
-  ui.serviceAuthWidget->horizontalHeader()->setResizeMode(0, QHeaderView::Stretch);
-  ui.serviceAuthWidget->horizontalHeader()->setResizeMode(1, QHeaderView::Stretch);
-  ui.serviceAuthWidget->horizontalHeader()->resizeSection(1,180);  
+  ui.serviceAuthWidget->horizontalHeader()->resizeSection(1,180);
+  ui.serviceAuthWidget->horizontalHeader()->resizeSection(2,60);
+  ui.serviceAuthWidget->horizontalHeader()->setResizeMode(0,
+   QHeaderView::Stretch);
+  ui.serviceAuthWidget->horizontalHeader()->setResizeMode(1,
+   QHeaderView::Stretch);
+  ui.serviceAuthWidget->horizontalHeader()->setResizeMode(2,
+   QHeaderView::Stretch);
   ui.serviceAuthWidget->verticalHeader()->hide();
+  ui.serviceAccessWidget->horizontalHeader()->resizeSection(1,180);
+  ui.serviceAccessWidget->horizontalHeader()->setResizeMode(0,
+   QHeaderView::Stretch);
+  ui.serviceAccessWidget->horizontalHeader()->setResizeMode(1,
+   QHeaderView::Stretch);
+  ui.serviceAccessWidget->verticalHeader()->hide();
 
   connect(ui.addServiceBtn, SIGNAL(clicked()), this, SLOT(addService()));
   connect(ui.removeServiceBtn, SIGNAL(clicked()), this, SLOT(removeService()));
   connect(ui.copyServiceBtn, SIGNAL(clicked()), this, SLOT(copyToClipboard()));
-  connect(ui.browseServiceBtn, SIGNAL(clicked()), this, SLOT(browseDirectory()));
-  connect(ui.serviceWidget, SIGNAL(itemClicked(QTableWidgetItem*)), this,
-   SLOT(serviceSelectionChanged()));
+  connect(ui.browseServiceBtn, SIGNAL(clicked()), this,
+   SLOT(browseDirectory()));
+  connect(ui.serviceWidget, SIGNAL(currentItemChanged ( QTableWidgetItem*,
+   QTableWidgetItem* )), this,
+   SLOT(serviceSelectionChanged(QTableWidgetItem*, QTableWidgetItem*)));
   connect(ui.serviceWidget, SIGNAL(itemChanged(QTableWidgetItem*)), this,
    SLOT(valueChanged()));
   connect(ui.restrictAccessCheckBox, SIGNAL(stateChanged(int)), this,
@@ -83,7 +106,13 @@
   connect(ui.copyServiceAuthBtn, SIGNAL(clicked()), this,
    SLOT(copyServiceAuthBtnClicked()));
   connect(ui.serviceAuthWidget, SIGNAL(itemChanged(QTableWidgetItem*)), this,
-   SLOT(authValueChanged()));
+   SLOT(clientAuthValueChanged()));
+  connect(ui.serviceAuthWidget, SIGNAL(itemClicked(QTableWidgetItem*)), this,
+   SLOT(serviceAuthSelectionChanged()));
+  connect(ui.serviceAccessWidget, SIGNAL(itemChanged(QTableWidgetItem*)), this,
+   SLOT(serviceAccessValueChanged()));
+  connect(ui.serviceAccessWidget, SIGNAL(itemClicked(QTableWidgetItem*)), this,
+   SLOT(serviceAccessSelectionChanged()));
 }
 
 /** Destructor */
@@ -98,28 +127,30 @@
 {
   QList<Service> serviceList;
   QList<Service> publishedServices;
-  int index = 0;
-  while(index < ui.serviceWidget->rowCount()) {
-    QString address = ui.serviceWidget->item(index,0)->text();
-    QString virtualPort = ui.serviceWidget->item(index,1)->text();
-    QString physicalAddress = ui.serviceWidget->item(index,2)->text();
-    QString directoryPath = ui.serviceWidget->item(index,3)->text();
-    bool enabled = _services->value(index).enabled();
-    QList<User> users = _services->value(index).users();
-    Service temp(address, virtualPort, physicalAddress, directoryPath,
-     enabled);
-    temp.setAdditionalServiceOptions(_services->value(ui.serviceWidget->
-     currentRow()).additionalServiceOptions());
-    temp.setUsers(users);
-    serviceList.push_back(temp);
-    if(enabled) {
-      publishedServices.push_back(temp);
-    }
-  index++;
-  }
   bool save;
   save = checkBeforeSaving(serviceList);
   if(save) {
+    //store all accessed Services
+    _serviceSettings->setServiceAuthorizationData(_consumedServices->values());
+    int index = 0;
+    while(index < ui.serviceWidget->rowCount()) {
+      QString address = ui.serviceWidget->item(index,0)->text();
+      QString virtualPort = ui.serviceWidget->item(index,1)->text();
+      QString physicalAddress = ui.serviceWidget->item(index,2)->text();
+      QString directoryPath = ui.serviceWidget->item(index,3)->text();
+      bool enabled = _services->value(index).enabled();
+      QList<UserAuthorizationData> users = _services->value(index).users();
+      Service temp(address, virtualPort, physicalAddress, directoryPath,
+       enabled);
+      temp.setAdditionalServiceOptions(_services->value(ui.serviceWidget->
+       currentRow()).additionalServiceOptions());
+      temp.setUsers(users);
+      serviceList.push_back(temp);
+      if(enabled) {
+        publishedServices.push_back(temp);
+      }
+    index++;
+    }
     ServiceList sList;
     if(serviceList.size() > 0) {
       sList.setServices(serviceList);
@@ -155,6 +186,96 @@
       break;
     }
   }
+  if(ui.serviceAuthWidget->rowCount() > 0) {
+    bool everythingcorrect = true;
+    for(int i = 0;i < ui.serviceAuthWidget->rowCount(); i++) {
+      QTableWidgetItem *item = ui.serviceAuthWidget->item(i, 1);
+      if(item->text() == NULL || item->text().length() == 0) {
+        everythingcorrect = false;
+        break;
+      }
+    }
+    if(everythingcorrect) {
+      //just save all values
+      QList<UserAuthorizationData> users;
+      Service s = _services->take(ui.serviceWidget->currentRow());
+      for(int i = 0; i < ui.serviceAuthWidget->rowCount(); i++) {
+        QString authdata, identification;
+        bool enabled = false;
+        QTableWidgetItem *selItem = ui.serviceAuthWidget->item(i, 1);
+        authdata = ui.serviceAuthWidget->item(i,0)->text();
+        identification = selItem->text();
+        if(ui.serviceAuthWidget->item(i,2)->checkState() == Qt::Checked) {
+          enabled = true;
+        }
+        UserAuthorizationData u(authdata, identification);
+        u.setEnabled(enabled);
+        users.push_back(u);
+      }
+      s.setUsers(users);
+      _services->insert(ui.serviceWidget->currentRow(), s);
+    } else {
+      //aks the user how to react
+      if(VMessageBox::warning(this, tr("Error"), tr("Some of the required user\
+       authorization identification fields are empty. Do you want Vidalia to\
+       create some dummy values you can change later? If not, the corresponding\
+       authorization data is going to be deleted."),
+        VMessageBox::Yes, VMessageBox::No) == VMessageBox::Yes) {
+          //create a list containing of all identifications to ensure
+          //no double ones
+          QList<QString> identifications;
+          for(int i = 0; i < ui.serviceAuthWidget->rowCount(); i++) {
+            QTableWidgetItem *selectedItem = ui.serviceAuthWidget->item(i, 1);
+            if(selectedItem->text() != NULL && selectedItem->text().
+              length() > 0) {
+              identifications.push_back(selectedItem->text());
+            }
+          }
+          //create dummy values and save them
+          for(int i = 0; i < ui.serviceAuthWidget->rowCount(); i++) {
+            QTableWidgetItem *currentItem = ui.serviceAuthWidget->item(i, 1);
+            if(currentItem->text() == NULL || currentItem->text().length()==0){
+              QString dummy = "user_";
+              dummy.append(QString::number(i));
+              int i2 = i;
+              while(identifications.contains(dummy)) {
+                int endindex = dummy.length();
+                i2++;
+                dummy.remove(5, (endindex-5));
+                dummy.append(QString::number(i2));
+              }
+              currentItem->setText(dummy);
+            }
+          }
+        } else {
+           //discard the incorrect ones
+           for(int i = 0; i < ui.serviceAuthWidget->rowCount(); i++) {
+             QTableWidgetItem *currentItem = ui.serviceAuthWidget->item(i, 1);
+             if(currentItem->text() == NULL || currentItem->text().length()==0){
+               ui.serviceAuthWidget->removeRow(i);
+               i--;
+             }
+           }
+       }
+       QList<UserAuthorizationData> users;
+       Service s = _services->take(ui.serviceWidget->currentRow());
+       for(int i = 0; i < ui.serviceAuthWidget->rowCount(); i++) {
+         QString authdata, identification;
+         bool enabled = false;
+         QTableWidgetItem *curItem = ui.serviceAuthWidget->item(i, 1);
+         authdata = ui.serviceAuthWidget->item(i,0)->text();
+         identification = curItem->text();
+         if(ui.serviceAuthWidget->item(i,2)->checkState() == Qt::Checked) {
+           enabled = true;
+         }
+         UserAuthorizationData u(authdata, identification);
+         u.setEnabled(enabled);
+         users.push_back(u);
+       }
+       s.setUsers(users);
+       _services->insert(ui.serviceWidget->currentRow(), s);
+   }
+  }
   return result;
 }
 
@@ -165,6 +286,7 @@
   QString serviceConfString;
   QString errmsg = "Error while trying to publish services.";
   QListIterator<Service> it(services);
+  QList<UserAuthorizationData> publishedUsers;
   bool first = true;
   while(it.hasNext()) {
     Service temp = it.next();
@@ -174,11 +296,40 @@
      string_escape(temp.virtualPort() +
      (temp.physicalAddressPort().isEmpty() ? "" : " " +
       temp.physicalAddressPort())));
+    QListIterator<UserAuthorizationData> it (temp.users());
+    while(it.hasNext()) {
+      UserAuthorizationData user = it.next();
+      if(user.enabled() == true) {
+        publishedUsers.push_back(user);
+      }
+    }
+    if(publishedUsers.size() > 0) {
+      serviceConfString.append(" hiddenserviceversion=\"2\" \
+       hiddenserviceauthorizeclient="+
+       string_escape(createUserAuthStringForTor(publishedUsers)));
+    }
     serviceConfString.append(" "+ temp.additionalServiceOptions());
   }
   _serviceSettings->applyServices(serviceConfString, &errmsg);
 }
 
+/** this method creates the configuration string for tor including the
+ * user authorization*/
+QString
+ServicePage::createUserAuthStringForTor(QList<UserAuthorizationData> users)
+{
+  QString result = "";
+  QListIterator<UserAuthorizationData> it(users);
+  while(it.hasNext()) {
+    UserAuthorizationData temp = it.next();
+    result.append(temp.identification());
+    result.append(",");
+  }
+  result.remove(result.length()-1, 1);
+  return result;
+}
+
+/** Called when the user checks the box to restrict access to hidden service*/
 void
 ServicePage::clientAuthChecked(int state)
 {
@@ -194,32 +345,37 @@
 void
 ServicePage::load()
 {
+  //clean the widgets
+  int rows = ui.serviceWidget->rowCount();
+  for(int i = 0; i < rows; i++) {
+    ui.serviceWidget->removeRow(0);
+  }
+  int rows2 = ui.serviceAuthWidget->rowCount();
+  for(int i = 0; i < rows2; i++) {
+    ui.serviceAuthWidget->removeRow(0);
+  }
   ui.removeServiceBtn->setEnabled(false);
   ui.copyServiceBtn->setEnabled(false);
   ui.browseServiceBtn->setEnabled(false);
   ui.authClientsGroupBox->setVisible(false);
   ui.restrictAccessCheckBox->setCheckState(Qt::Unchecked);
   ui.restrictAccessCheckBox->setEnabled(false);
+  ui.removeServiceAuthBtn->setEnabled(false);
+  ui.copyServiceAuthBtn->setEnabled(false);
   // get all services
-  _services = new QMap<int, Service>();
-  _torServices = new QMap<QString, Service>();
+  _services->clear();
+  _torServices->clear();
+  _consumedServices->clear();
   QList<Service> torServiceList;
-
+  QList<Service> completeList;
   QString torConfigurationString = _serviceSettings->
    getHiddenServiceDirectories();
   torServiceList = extractSingleServices(torConfigurationString);
-  QList<Service> completeList = torServiceList;
   // the services stored with vidalia
   ServiceList serviceList = _serviceSettings->getServices();
   QList<Service> serviceSettingsList = serviceList.services();
-  QListIterator<Service> it(serviceSettingsList);
-  // check whether a service is already in the list because he is published
-  while(it.hasNext()) {
-    Service temp = it.next();
-    if(isServicePublished(temp, torServiceList) == false) {
-      completeList.push_back(temp);
-    }
-  }
+  // merge the services of Vidalia and Tor
+  completeList = mergeServices(torServiceList, serviceSettingsList);
   // generate the _services data structure used during vidalia session
   QListIterator<Service> it2(completeList);
   int index = 0;
@@ -228,7 +384,10 @@
     _services->insert(index, tempService);
     index++;
   }
-  initServiceTable(_services);
+  initServiceTable();
+  QList<ServiceAuthorizationData> authdataList;
+  authdataList = _serviceSettings->getServiceAuthorizationData();
+  initServiceAccessTable(authdataList);
 }
 
 /** this method returns a list of services by parsing the configuration
@@ -248,12 +407,13 @@
   return list;
 }
 
-/** this return a Service by parseing the configuration string
- *  of Tor and storeing its values into the object */
+/** this method returns a Service by parseing the configuration string
+ *  of Tor and storing its values into the object */
 Service
 ServicePage::generateService(QString s)
 {
   QString additionalOptions = s;
+  bool userAuthConfigured = false;
   // remove directory
   int index = additionalOptions.indexOf("250",1);
   additionalOptions.remove(0, index+4);
@@ -263,6 +423,22 @@
   int endindex = additionalOptions.indexOf("250", startindex);
   if(endindex != -1) {
     additionalOptions.remove(startindex, (endindex-startindex)+4);
+    //remove first appearance of hiddenserviceauthorizeclient
+    int indexstart = additionalOptions.indexOf("hiddenserviceauthorizeclient",
+     0, Qt::CaseInsensitive);
+     int indexend = additionalOptions.indexOf("250", indexstart);
+     if(indexend != -1) {
+       additionalOptions.remove(indexstart, (indexend-indexstart)+4);
+     } else {
+       indexend = additionalOptions.indexOf("\n", indexstart);
+       if(indexend != -1) {
+         additionalOptions.remove(indexstart, (indexend-indexstart));
+       } else {
+         indexend = additionalOptions.length()-1;
+         additionalOptions.remove(indexstart, (indexend-indexstart));
+       }
+       additionalOptions.remove(indexstart, (indexend-indexstart));
+     }
     //remove all appearances of "250"
     while(additionalOptions.contains("250")) {
       int i = additionalOptions.indexOf("250", 0);
@@ -308,25 +484,162 @@
        QString tempVirtualPort = strList3.first();
        virtualPort = tempVirtualPort.remove(0, 1);
   }
+  //get all users that are in the client-keys file
+  QList<UserAuthorizationData> allUsers = parseClientKeys(serviceDir);
+  //get all actual users by parsing the hostname file
+  QList<UserAuthorizationData> actualUsers;
+  if(s.contains("HiddenServiceAuthorizeClient")) {
+    userAuthConfigured = true;
+    QStringList strList5 = s.split("HiddenServiceAuthorizeClient");
+    strList5.removeFirst();
+    QStringList strList6 = strList5.first().split("\n");
+    strList6.first().remove(0,1);
+    QStringList userList = strList6.first().split(",");
+    foreach(QString user, userList) {
+      QString authdata, filereader;
+      int index = 0;
+      //remove the users in the allUsers data structure,if they are actual users
+      while(index < allUsers.size()) {
+        UserAuthorizationData temp = allUsers.at(index);
+        if(temp.identification().compare(user) == 0) {
+          allUsers.removeAt(index);
+        }
+        index++;
+      }
+      //parse the hostname file to get the authorization data
+      QString dir = serviceDir;
+      dir.append("/hostname");
+      QFile file(dir);
+      if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+        filereader = "[Directory not found]";
+      } else {
+        QTextStream in(&file);
+        while (!in.atEnd()) {
+          filereader.append(in.readLine());
+          filereader.append("\n");
+        }
+        QStringList strList7 = filereader.split("\n");
+        //remove first 5 lines
+        for(int i = 0; i < 5; i++) {
+          strList7.removeFirst();
+        }
+        while(strList7.isEmpty() == false) {
+          QString temp = strList7.first();
+          if(temp.contains(""+user)){
+            break;
+          } else {
+             strList7.removeFirst();
+          }
+        }
+        QString temp = strList7.first();
+        QStringList strList8 = temp.split("#");
+        authdata = strList8.first();
+        authdata.remove(authdata.length()-1,1);
+      }
+      UserAuthorizationData u(authdata, user);
+      actualUsers.push_back(u);
+    }
+  }
+  //if there are some users not in the actual users data structure,
+  //but in client-keys
+  if(allUsers.size() > 0) {
+    QListIterator<UserAuthorizationData> it2(allUsers);
+    while(it2.hasNext()) {
+      UserAuthorizationData tempData = it2.next();
+      actualUsers.push_back(tempData);
+    }
+  }
   //get .onion address
-  QString serviceHostnameDir = serviceDir;
-  serviceHostnameDir.append("/");
-  serviceHostnameDir.append("hostname");
-  QFile file(serviceHostnameDir);
+  if(userAuthConfigured == true) {
+    address = "[Client Auth Configured]";
+  } else {
+      QString serviceHostnameDir = serviceDir;
+      serviceHostnameDir.append("/");
+      serviceHostnameDir.append("hostname");
+      QFile file(serviceHostnameDir);
+      if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+        address = "[Directory not found]";
+      } else {
+          QTextStream in(&file);
+          QString hostname;
+          while (!in.atEnd()) {
+            hostname.append(in.readLine());
+          }
+          address = hostname;
+        }
+  }
+  Service service(address, virtualPort, physAddressPort, serviceDir, true);
+  service.setAdditionalServiceOptions(additionalOptions);
+  service.setUsers(actualUsers);
+  _torServices->insert(serviceDir, service);
+  return service;
+}
+
+/** this method is called to parse the client_keys file in order to
+ *  get all users that had a authorization for the Service
+ * @return a list of all users found in client_keys*/
+QList<UserAuthorizationData>
+ServicePage::parseClientKeys(QString dir)
+{
+  QList<UserAuthorizationData> result;
+  QString value;
+  QFile file(dir.append("/client_keys"));
   if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
-    address = "[Directory not found]";
+    return result;
   } else {
       QTextStream in(&file);
-      QString hostname;
+      QString content;
       while (!in.atEnd()) {
-        hostname.append(in.readLine());
+        content.append(in.readLine());
+        content.append("\n");
       }
-      address = hostname;
+      value = content;
+  }
+  QStringList strList = value.split("client-name");
+  strList.removeFirst();
+  foreach(QString user, strList) {
+    QStringList strList2 = user.split("\n");
+    UserAuthorizationData u("[Created by Tor]", strList2.first().trimmed());
+    u.setEnabled(false);
+    result.push_back(u);
+  }
+  return result;
+}
+
+/** this method merges the list of services received from Vidalia and Tor
+  * @return a list containing all services without double entries */
+QList<Service>
+ServicePage::mergeServices(QList<Service> torServices,
+ QList<Service> vidaliaServices)
+{
+  QList<Service> result;
+  QListIterator<Service> it(vidaliaServices);
+  while(it.hasNext()) {
+    Service temp = it.next();
+    if(isServicePublished(temp, torServices) == false) {
+      result.push_back(temp);
+    } else {
+      QListIterator<Service> it2(torServices);
+      while(it2.hasNext()) {
+        Service temp2 = it2.next();
+        if(temp2.serviceDirectory().compare(temp.serviceDirectory()) == 0) {
+          //merge the users!
+          QList<UserAuthorizationData> users = temp2.users();
+          QListIterator<UserAuthorizationData> it3(users);
+          while(it3.hasNext()) {
+            UserAuthorizationData user = it3.next();
+            if(temp2.isMember(user) == false) {
+              user.setEnabled(false);
+              users.push_back(user);
+              temp2.setUsers(users);
+            }
+          }
+        }
+      }
     }
-  Service service(address, virtualPort, physAddressPort, serviceDir, true);
-  service.setAdditionalServiceOptions(additionalOptions);
-  _torServices->insert(serviceDir, service);
-  return service;
+  }
+  result << torServices;
+  return result;
 }
 
 /** this method checks either a service is published or not */
@@ -346,20 +659,10 @@
 /** this method creates/displays the values for each service
  *  shown in the service listing */
 void
-ServicePage::initServiceTable(QMap<int, Service>* _services)
+ServicePage::initServiceTable()
 {
-  // clean the widget
-  int rows = ui.serviceWidget->rowCount();
-  for(int i = 0; i < rows; i++) {
-    ui.serviceWidget->removeRow(0);
-  }
-  int rows2 = ui.serviceAuthWidget->rowCount();
-  for(int i = 0; i < rows2; i++) {
-    ui.serviceAuthWidget->removeRow(0);
-  }
-  //for each service
-  int index = 0;
-  while(index < _services->size()) {
+  //for each provided service
+  for(int index = 0; index < _services->size(); index++) {
     Service tempService = _services->value(index);
     ui.serviceWidget->insertRow(index);
     QTableWidgetItem *cboxitem = new QTableWidgetItem();
@@ -381,8 +684,13 @@
             while (!in.atEnd()) {
               hostname.append(in.readLine());
             }
-            addressitem->setText(hostname);
-            tempService.setServiceAddress(hostname);
+            if(hostname.length() > 40) {
+              addressitem->setText("[Client Auth Configured]");
+              tempService.setServiceAddress("[Client Auth Configured]");
+            } else {
+              addressitem->setText(hostname);
+              tempService.setServiceAddress(hostname);
+            }
           }
       }
     addressitem->setData(32, addressitem->text());
@@ -407,10 +715,31 @@
     ui.serviceWidget->setItem(index, 2, targetitem);
     ui.serviceWidget->setItem(index, 3, serviceDir);
     ui.serviceWidget->setItem(index, 4, cboxitem);
-    index++;
   }
 }
 
+void
+ServicePage::initServiceAccessTable(QList<ServiceAuthorizationData> authdataList)
+{
+  while(ui.serviceAccessWidget->rowCount() > 0) {
+    ui.serviceAccessWidget->removeRow(0);
+  }
+  foreach(ServiceAuthorizationData tempService, authdataList) {
+    int rows = ui.serviceAccessWidget->rowCount();
+    QString authdata = tempService.authdata();
+    QString identification = tempService.identification();
+    ServiceAuthorizationData s(authdata, identification);
+    ui.serviceAccessWidget->insertRow(rows);
+    QTableWidgetItem* authdataItem = new QTableWidgetItem(authdata);
+    QTableWidgetItem* identificationItem = new QTableWidgetItem(identification);
+    identificationItem->setData(32, identification);
+    authdataItem->setData(32, authdata);
+    ui.serviceAccessWidget->setItem(rows, 0, authdataItem);
+    ui.serviceAccessWidget->setItem(rows, 1, identificationItem);
+    _consumedServices->insert(identification, s);
+  }
+}
+
 /** this method is called when the user clicks the "Add"-Button
  *  it generates a new empty table entrie(row) */
 void
@@ -456,7 +785,10 @@
         _services->insert(index, s);
       }
     }
-    serviceSelectionChanged();
+    if(ui.serviceWidget->rowCount() == 0) {
+      ui.restrictAccessCheckBox->setCheckState(Qt::Unchecked);
+      ui.authClientsGroupBox->setVisible(false);
+    }
 }
 
 /** this method is called when the user clicks on the "Copy"-Button, it
@@ -492,7 +824,6 @@
       QString dirname = QFileDialog::getExistingDirectory(this,
        tr("Select Service Directory"), "",
         QFileDialog::ShowDirsOnly|QFileDialog::DontResolveSymlinks);
-
       if (dirname.isEmpty()) {
         return;
       }
@@ -503,29 +834,126 @@
     }
 }
 
-/** this method is called when the selects an other tablewidgetitem */
+/** this method is called when the selects an other QTableWidgetItem in
+ * the Service table */
 void
-ServicePage::serviceSelectionChanged()
+ServicePage::serviceSelectionChanged(QTableWidgetItem* current,
+ QTableWidgetItem * previous)
 {
+  //shows whether the previous service selection is choosen or not
+  if(previous != NULL && current != NULL && previous != current) {
+    //only if there are entries in the authorization widget
+    if(ui.serviceAuthWidget->rowCount() > 0) {
+      //check if all required fields are set
+      if(!checkBeforeChanging()) {
+        if(VMessageBox::warning(this, tr("Error"), tr("Some of the required\
+         identification fields are empty. Do you want Vidalia to create some\
+         dummy values you can change later? If not, the corresponding\
+         authorization data is going to be deleted."),
+          VMessageBox::Yes, VMessageBox::No) == VMessageBox::No) {
+           //save only the correct ones
+           QList<UserAuthorizationData> users;
+           for(int i = 0; i < ui.serviceAuthWidget->rowCount(); i++) {
+            QTableWidgetItem *idItem = ui.serviceAuthWidget->item(i, 1);
+            if(idItem != NULL && idItem->text() != NULL &&
+             idItem->text().length() > 0) {
+              QString authdata, identification;
+              bool enabled = false;
+              authdata = ui.serviceAuthWidget->item(i, 0)->text();
+              identification = ui.serviceAuthWidget->item(i, 1)->text();
+              UserAuthorizationData u(authdata, identification);
+              if(ui.serviceAuthWidget->item(i,2)->checkState() == Qt::Checked) {
+                enabled = true;
+              }
+              u.setEnabled(enabled);
+              users.push_back(u);
+            }
+          }
+          Service s = _services->take(previous->row());
+          s.setUsers(users);
+          _services->insert(previous->row(), s);
+          } else {
+            //create a list containing all identifications to ensure
+            //no double ones
+            QList<QString> identifications;
+            for(int i = 0; i < ui.serviceAuthWidget->rowCount(); i++) {
+              QTableWidgetItem *selectedItem = ui.serviceAuthWidget->item(i, 1);
+              if(selectedItem->text() != NULL &&
+               selectedItem->text().length() > 0) {
+                identifications.push_back(selectedItem->text());
+              }
+            }
+            //create dummy values and save them
+            for(int i = 0; i < ui.serviceAuthWidget->rowCount(); i++) {
+              QTableWidgetItem *currentItem = ui.serviceAuthWidget->item(i, 1);
+              if(currentItem->text() == NULL||currentItem->text().length()==0){
+                QString dummy = "user_";
+                dummy.append(QString::number(i));
+                int i2 = i;
+                while(identifications.contains(dummy)) {
+                  int endindex = dummy.length();
+                  i2++;
+                  dummy.remove(5, (endindex-5));
+                  dummy.append(QString::number(i2));
+                }
+                currentItem->setText(dummy);
+              }
+            }
+             QList<UserAuthorizationData> users;
+             for(int i = 0; i < ui.serviceAuthWidget->rowCount(); i++) {
+               QString authdata, identification;
+               bool enabled;
+               authdata = ui.serviceAuthWidget->item(i, 0)->text();
+               identification = ui.serviceAuthWidget->item(i, 1)->text();
+               UserAuthorizationData u(authdata, identification);
+               if(ui.serviceAuthWidget->item(i,2)->checkState()==Qt::Checked) {
+                enabled = true;
+               }
+               u.setEnabled(enabled);
+               users.push_back(u);
+              }
+             Service s = _services->take(previous->row());
+             s.setUsers(users);
+             _services->insert(previous->row(), s);
+           }
+      } else {
+        //all required fields are set
+        QList<UserAuthorizationData> users;
+        for(int i = 0; i < ui.serviceAuthWidget->rowCount(); i++) {
+          QString authdata, identification;
+          bool enabled = false;
+          authdata = ui.serviceAuthWidget->item(i, 0)->text();
+          identification = ui.serviceAuthWidget->item(i, 1)->text();
+          UserAuthorizationData u(authdata, identification);
+          if(ui.serviceAuthWidget->item(i,2)->checkState() == Qt::Checked) {
+            enabled = true;
+          }
+          u.setEnabled(enabled);
+          users.push_back(u);
+        }
+        Service s = _services->take(previous->row());
+        s.setUsers(users);
+        _services->insert(previous->row(), s);
+       }
+      }
+    }
   bool emptyTable = false;
   if(ui.serviceWidget->rowCount() > 0) {
     ui.removeServiceBtn->setEnabled(true);
     ui.copyServiceBtn->setEnabled(true);
     ui.browseServiceBtn->setEnabled(true);
     ui.restrictAccessCheckBox->setEnabled(true);
-    //TODO erst prüfen ob gechecket ist!
-    ui.addServiceAuthBtn->setEnabled(true);
-    ui.removeServiceAuthBtn->setEnabled(true);
-    ui.copyServiceAuthBtn->setEnabled(true);
+    ui.addClientAuthBtn->setEnabled(true);
+    ui.removeClientAuthBtn->setEnabled(true);
+    ui.copyClientAuthBtn->setEnabled(true);
   } else {
       ui.removeServiceBtn->setEnabled(false);
       ui.copyServiceBtn->setEnabled(false);
       ui.browseServiceBtn->setEnabled(false);
       ui.restrictAccessCheckBox->setEnabled(false);
-      //TODO
-      ui.addServiceAuthBtn->setEnabled(false);
-      ui.removeServiceAuthBtn->setEnabled(false);
-      ui.copyServiceAuthBtn->setEnabled(false);
+      ui.addClientAuthBtn->setEnabled(false);
+      ui.removeClientAuthBtn->setEnabled(false);
+      ui.copyClientAuthBtn->setEnabled(false);
       emptyTable = true;
     }
   int currentRow = ui.serviceWidget->currentRow();
@@ -536,29 +964,42 @@
       ui.copyServiceBtn->setEnabled(b);
     }
   }
-  // clean the user authorization widget
   int rows = ui.serviceAuthWidget->rowCount();
   for(int i = 0; i < rows; i++) {
     ui.serviceAuthWidget->removeRow(0);
   }
-  // show the users with user authorization for the service
+  //show the users with user authorization for the selected service
   Service selService = _services->take(ui.serviceWidget->currentRow());
-  QList<User> assoziatedUsers = selService.users();
-  int rowcount = 0;
-  QListIterator<User> it(assoziatedUsers);
-  while(it.hasNext()) {
-    User tempUser = it.next();
-  	ui.serviceAuthWidget->insertRow(rowcount);
-    QTableWidgetItem* authdataItem = new QTableWidgetItem(tempUser.authdata());
-    authdataItem->setFlags(Qt::ItemIsSelectable);
-    QTableWidgetItem* commentItem = new QTableWidgetItem(tempUser.comment());
-    ui.serviceAuthWidget->setItem(rowcount, 0, authdataItem);
-    ui.serviceAuthWidget->setItem(rowcount, 1, commentItem);
-    rowcount++;
+  QList<UserAuthorizationData> assoziatedUsers = selService.users();
+  if(assoziatedUsers.size() == 0) {
+    ui.authClientsGroupBox->setVisible(false);
+    ui.restrictAccessCheckBox->setCheckState(Qt::Unchecked);
+  } else {
+      int rowcount = 0;
+      QListIterator<UserAuthorizationData> it(assoziatedUsers);
+      while(it.hasNext()) {
+        UserAuthorizationData tempUser = it.next();
+        ui.serviceAuthWidget->insertRow(rowcount);
+        QTableWidgetItem* authdataItem = new QTableWidgetItem(
+         tempUser.authdata());
+        authdataItem->setFlags(Qt::ItemIsSelectable);
+        QTableWidgetItem* identificationItem = new QTableWidgetItem;
+        identificationItem->setData(32, tempUser.identification());
+        identificationItem->setText(tempUser.identification());
+        QTableWidgetItem *cboxitem = new QTableWidgetItem();
+        cboxitem->setFlags(Qt::ItemIsSelectable);
+        if(tempUser.enabled()) {
+          cboxitem->setCheckState(Qt::Checked);
+        } else {
+          cboxitem->setCheckState(Qt::Unchecked);
+        }
+        ui.serviceAuthWidget->setItem(rowcount, 0, authdataItem);
+        ui.serviceAuthWidget->setItem(rowcount, 1, identificationItem);
+        ui.serviceAuthWidget->setItem(rowcount, 2, cboxitem);
+        rowcount++;
+      }
   }
   _services->insert(ui.serviceWidget->currentRow(), selService);
-  QTableWidgetItem* item = ui.serviceWidget->item(ui.serviceWidget->
-   currentRow(), 3);
   QString selDir = _services->value(ui.serviceWidget->currentRow()).
    serviceDirectory();
   QList<QString> strList =  _torServices->keys();
@@ -674,33 +1115,26 @@
   }
 }
 
+/** Called when the user wants to add a client with authorization */
 void
 ServicePage::addClientAuthBtnClicked()
 {
-  QString comment = ui.privateCommentLineProvider->text();
-  if(comment.length() > 0)
-  {
-   QTableWidgetItem *commentItem = new QTableWidgetItem();
+   QTableWidgetItem *identificationItem = new QTableWidgetItem();
    QTableWidgetItem *addressItem = new QTableWidgetItem();
+   QTableWidgetItem *cboxItem = new QTableWidgetItem();
+   cboxItem->setFlags(Qt::ItemIsSelectable);
+   cboxItem->setCheckState(Qt::Checked);
+   cboxItem->setTextAlignment(Qt::AlignCenter);
    addressItem->setFlags(Qt::ItemIsSelectable);
-   commentItem->setText(comment);
    addressItem->setText("[Created by Tor]");
    int rows = ui.serviceAuthWidget->rowCount();
    ui.serviceAuthWidget->insertRow(rows);
    ui.serviceAuthWidget->setItem(rows, 0, addressItem);
-   ui.serviceAuthWidget->setItem(rows, 1, commentItem);
-   ui.privateCommentLineProvider->clear();
-   User u(comment, "[Created by Tor]");
-   Service s = _services->take(ui.serviceWidget->currentRow());
-   s.addUser(u);
-   _services->insert(ui.serviceWidget->currentRow(), s);
-  } else {
-  	VMessageBox::warning(this, tr("Error"),
-        tr("Please choose a comment for the user, e.g. a name."),
-        VMessageBox::Ok);
-  }
+   ui.serviceAuthWidget->setItem(rows, 1, identificationItem);
+   ui.serviceAuthWidget->setItem(rows, 2, cboxItem);
 }
 
+/** Called when the user wants to remove a client with authorization */
 void
 ServicePage::removeClientAuthBtnClicked()
 {
@@ -711,10 +1145,29 @@
      VMessageBox::Ok);
     return;
   } else {
+    QTableWidgetItem *item = ui.serviceAuthWidget->item(selrow, 1);
+    if(item != NULL && item->text().length() > 0) {
+      Service s = _services->take(ui.serviceWidget->currentRow());
+      QList<UserAuthorizationData> users = s.users();
+      int index = 0;
+      while(index < users.size()) {
+        UserAuthorizationData temp = users.at(index);
+        if(temp.identification().compare(item->text()) == 0) {
+          users.removeAt(index);
+          break;
+        }
+        index++;
+      }
+      s.setUsers(users);
+      _services->insert(ui.serviceWidget->currentRow(), s);
+    }
     ui.serviceAuthWidget->removeRow(selrow);
   }
+  serviceAuthSelectionChanged();
 }
 
+/** Called when the user wants to copy the authorization of a client to
+ * the clipboard*/
 void
 ServicePage::copyClientAuthBtnClicked()
 {
@@ -728,28 +1181,327 @@
       QClipboard *clipboard = QApplication::clipboard();
       QString clipboardText;
       QTableWidgetItem* selectedItem = ui.serviceAuthWidget->item(selrow,0);
-      clipboardText.append(selectedItem->text());
+      QString authString = selectedItem->text();
+      QStringList splitList = authString.split(".onion");
+      QString onionAdress = splitList.first().append(".onion");
+      clipboardText.append(onionAdress);
       clipboard->setText(clipboardText);
     }
 }
 
+/** Called when the user wants to store authorization for a service*/
 void
 ServicePage::addServiceAuthBtnClicked()
 {
+  QString serviceAuthdata, serviceIdentification;
+  serviceAuthdata = ui.authLineAccess->text();
+  serviceIdentification = ui.commentLineAccess->text();
+  if(serviceAuthdata.length() == 0 || serviceIdentification.length() == 0) {
+    VMessageBox::warning(this, tr("Error"), tr("Please fill out both fields."),
+     VMessageBox::Ok);
+     return;
+  } else {
+    for(int i = 0; i < ui.serviceAccessWidget->rowCount(); i++) {
+      QString tempidentification = ui.serviceAccessWidget->item(i, 1)->text();
+      if(serviceIdentification.compare(tempidentification) == 0) {
+        VMessageBox::warning(this, tr("Error"), tr("Identification has to be\
+        unique, try another one please."), VMessageBox::Ok);
+        ui.commentLineAccess->clear();
+        return;
+     }
+    }
+    int pos = 0;
+    if(_identificationValidator->validate(serviceIdentification, pos) ==
+     QValidator::Acceptable) {
+      if(validateServiceAuth(serviceAuthdata) == QValidator::Acceptable) {
+        int rows = ui.serviceAccessWidget->rowCount();
+        ui.serviceAccessWidget->insertRow(rows);
+        QTableWidgetItem* authItem = new QTableWidgetItem(serviceAuthdata);
+        QTableWidgetItem* identificationItem =
+         new QTableWidgetItem(serviceIdentification);
+        identificationItem->setData(32, serviceIdentification);
+        authItem->setData(32, serviceAuthdata);
+        ui.serviceAccessWidget->setItem(rows, 0, authItem);
+        ui.serviceAccessWidget->setItem(rows, 1, identificationItem);
+        ui.authLineAccess->clear();
+        ui.commentLineAccess->clear();
+        ServiceAuthorizationData s(serviceAuthdata, serviceIdentification);
+        _consumedServices->insert(serviceIdentification, s);
+      }
+    } else {
+      VMessageBox::warning(this, tr("Error"), tr("Invalid characters for the\
+       identification, only {[a-z][A-Z][0-9]+-_} allowed. The length has to be\
+       between 1 and 19."), VMessageBox::Ok);
+        ui.commentLineAccess->clear();
+        return;
+    }
+  }
 }
 
+/** this method is called in order to validate the service authorization
+ *  string a user wants to store within vidalia
+ *  @return a QValidator::State signalling whether the string is valid or not*/
+QValidator::State
+ServicePage::validateServiceAuth(QString authString)
+{
+  QStringList strList = authString.split(" ");
+  int pos = 0;
+  if(_onionAdressValidator->validate(strList.first(), pos) ==
+   QValidator::Acceptable) {
+    strList.removeFirst();
+    if(_cookieValidator->validate(strList.first(), pos) ==
+     QValidator::Acceptable) {
+      return QValidator::Acceptable;
+    } else {
+      VMessageBox::warning(this, tr("Error"), tr("Your cookie is not valid,\
+       please correct it."), VMessageBox::Ok);
+      return QValidator::Invalid;
+    }
+  } else {
+    VMessageBox::warning(this, tr("Error"), tr("Your onion adress is not valid,\
+     please correct it."), VMessageBox::Ok);
+    return QValidator::Invalid;
+  }
+}
+
+/** Called when the user wants to remove authorization data for a service */
 void
 ServicePage::removeServiceAuthBtnClicked()
 {
+  QString identification = ui.serviceAccessWidget->item(ui.serviceAccessWidget->
+   currentRow(), 1)->text();
+  _consumedServices->take(identification);
+  ui.serviceAccessWidget->removeRow(ui.serviceAccessWidget->currentRow());
 }
 
+/** Called when the user wants to copy athorization data for a service to
+ * the clipboard*/
 void
 ServicePage::copyServiceAuthBtnClicked()
 {
+  int selrow = ui.serviceAccessWidget->currentRow();
+  int rowCount = ui.serviceAccessWidget->rowCount();
+  if(selrow < 0 || selrow >= rowCount) {
+    VMessageBox::warning(this, tr("Error"), tr("Please select a service."),
+     VMessageBox::Ok);
+    return;
+  } else {
+      QClipboard *clipboard = QApplication::clipboard();
+      QString clipboardText;
+      QTableWidgetItem* selectedItem = ui.serviceAccessWidget->item(selrow,0);
+      QString authString = selectedItem->text();
+      QStringList splitList = authString.split(".onion");
+      QString onionAdress = splitList.first().append(".onion");
+      clipboardText.append(onionAdress);
+      clipboard->setText(clipboardText);
+    }
 }
-/**  ensure no double comments */
+
+/** Called when a value of the serviceAuthWidget is changed, to ensure only
+ * valid values*/
 void
-ServicePage::authValueChanged()
+ServicePage::clientAuthValueChanged()
 {
+  QTableWidgetItem* item;
+  item = ui.serviceAuthWidget->currentItem();
+  QString currentString;
+  QStringList values;
+  if (item == NULL || item->text() == NULL || item->text().length() == 0) {
+    // nothing to validate here
+    return;
+  } else {
+  currentString = item->text();
+  switch (item->column()) {
+ case 1: // identification
+  for(int i = 0; i < ui.serviceAuthWidget->rowCount(); i++) {
+      if(i != ui.serviceAuthWidget->currentRow()) {
+        QTableWidgetItem* currentItem = ui.serviceAuthWidget->item(i, 1);
+        if(currentItem == NULL || currentItem->text() == NULL ||
+         currentItem->text().length() == 0) {
+        } else {
+           values.push_back(currentItem->text());
+         }
+      }
+  }
+  if(values.contains(currentString)) {
+    VMessageBox::warning(this, tr("Error"), tr("The identification has to be\
+     unique, please choose a different one."),  VMessageBox::Ok);
+      if(item->data(32).toString() != NULL &&
+       item->data(32).toString().length() > 0) {
+        item->setText(item->data(32).toString());
+      } else {
+        item->setText("");
+       }
+  } else {
+    int pos = 0;
+    if(_identificationValidator->validate(currentString, pos) ==
+     QValidator::Acceptable) {
+      item->setData(32, currentString);
+    } else {
+      VMessageBox::warning(this, tr("Error"), tr("Invalid characters for the\
+       identification, only {[a-z][A-Z][0-9]+-_} allowed. The length has to be\
+       between 1 and 19."), VMessageBox::Ok);
+        if(item->data(32).toString() != NULL &&
+         item->data(32).toString().length() > 0) {
+          item->setText(item->data(32).toString());
+        } else {
+          item->setText("");
+         }
+      }
+   }
+  break;
+  }
+  }
 }
 
+/** Called when a value of the serviceAccessWidget is changed, to ensure
+ * only valid values*/
+void
+ServicePage::serviceAccessValueChanged()
+{
+  QString currentString, currentAuthdata;
+  QStringList values;
+  QTableWidgetItem *item = ui.serviceAccessWidget->item(
+   ui.serviceAccessWidget->currentRow(), 1);
+  QTableWidgetItem* authItem = ui.serviceAccessWidget->item(
+   ui.serviceAccessWidget->currentRow(), 0);
+  if(item == NULL || item->text() == NULL || item->text().length() == 0 ||
+    authItem == NULL) {
+    // nothing to validate here
+    return;
+  } else {
+    currentString = item->text();
+    for(int i = 0; i < ui.serviceAccessWidget->rowCount(); i++) {
+      if(i != ui.serviceAccessWidget->currentRow()) {
+        QTableWidgetItem* tempItem = ui.serviceAccessWidget->item(i, 1);
+        if(tempItem != NULL && tempItem->text() != NULL &&
+         tempItem->text().length() > 0) {
+          values.push_back(tempItem->text());
+        }
+      }
+    }
+    if(values.contains(currentString)) {
+      VMessageBox::warning(this, tr("Error"), tr("The identification has to be\
+      unique, please choose a different one."), VMessageBox::Ok);
+      if(item->data(32).toString() != NULL &&
+       item->data(32).toString().length() > 0) {
+          item->setText(item->data(32).toString());
+      } else {
+        item->setText("");
+       }
+    } else {
+      int pos = 0;
+      if(_identificationValidator->validate(currentString, pos) ==
+       QValidator::Acceptable) {
+        if(authItem->text() == NULL || authItem->text().length() == 0) {
+          VMessageBox::warning(this, tr("Error"), tr("No empty authorization\
+           allowed!"), VMessageBox::Ok);
+           if(authItem->data(32).toString() != NULL &&
+            authItem->data(32).toString().length() > 0) {
+             authItem->setText(authItem->data(32).toString());
+           } else {
+             authItem->setText("");
+           }
+        } else {
+          currentAuthdata = authItem->text();
+          if(validateServiceAuth(authItem->text()) == QValidator::Acceptable) {
+            authItem->setData(32, currentAuthdata);
+            authItem->setText(currentAuthdata);
+          } else {
+            if(authItem->data(32).toString() != NULL &&
+             authItem->data(32).toString().length() > 0) {
+               authItem->setText(authItem->data(32).toString());
+             } else {
+               authItem->setText("");
+             }
+          }
+        }
+      } else {
+        VMessageBox::warning(this, tr("Error"), tr("Invalid characters for the\
+         identification, only {[a-z][A-Z][0-9]+-_} allowed. The length has to\
+         be between 1 and 19."), VMessageBox::Ok);
+        if(item->data(32) == NULL || item->data(32).toString() == NULL ||
+         item->data(32).toString().length() <= 0) {
+          item->setText("");
+        } else {
+          item->setText(item->data(32).toString());
+         }
+      }
+    }
+  }
+}
+
+/** Called whenever the user selects a different service access
+ * entry(Consumed Services)*/
+void
+ServicePage::serviceAccessSelectionChanged()
+{
+  bool emptyTable = false;
+  if(ui.serviceAccessWidget->rowCount() > 0) {
+    ui.removeServiceAuthBtn->setEnabled(true);
+  } else {
+      ui.removeServiceAuthBtn->setEnabled(false);
+      ui.copyServiceAuthBtn->setEnabled(false);
+      emptyTable = true;
+    }
+  int currentRow = ui.serviceAccessWidget->currentRow();
+  if(emptyTable == false) {
+    QTableWidgetItem* item = ui.serviceAccessWidget->item(currentRow, 0);
+    if(item != NULL) {
+      bool b = item->text().contains(".onion");
+      ui.copyServiceAuthBtn->setEnabled(b);
+    }
+  }
+}
+
+/** Called whenever the user selects a different service authorization
+ * entry(Provided Services)*/
+void
+ServicePage::serviceAuthSelectionChanged()
+{
+  QTableWidgetItem* item = ui.serviceAuthWidget->currentItem();
+  if(item != NULL) {
+    int row = item->row();
+    QString address = ui.serviceAuthWidget->item(row,0)->text();
+    bool b = address.contains(".onion");
+    ui.copyClientAuthBtn->setEnabled(b);
+    switch (item->column()) {
+ case 2: //checkbox
+    Service selectedService = _services->take(ui.serviceWidget->currentRow());
+    UserAuthorizationData selectedUser;
+    QList<UserAuthorizationData> users = selectedService.users();
+    QString identity = ui.serviceAuthWidget->item(item->row(), 1)->text();
+    QListIterator<UserAuthorizationData> it(users);
+    while(it.hasNext()) {
+      UserAuthorizationData temp = it.next();
+      if(temp.identification().compare(identity) == 0) {
+        selectedUser = temp;
+      }
+    }
+    if(item->checkState() == Qt::Unchecked) {
+      item->setCheckState(Qt::Checked);
+      selectedUser.setEnabled(true);
+    } else {
+      item->setCheckState(Qt::Unchecked);
+      selectedUser.setEnabled(false);
+    }
+    break;
+    }
+  }
+}
+
+/** this method is called to ensure that all required fields are set
+  * before the saving starts.
+  * @return a boolean showing whether all required fields are set or not */
+bool
+ServicePage::checkBeforeChanging()
+{
+  for(int i = 0; i < ui.serviceAuthWidget->rowCount(); i++) {
+    QTableWidgetItem* item = ui.serviceAuthWidget->item(i,1);
+    if(item == NULL || item->text() == NULL || item->text().length() == 0) {
+      return false;
+    }
+  }
+  return true;
+}
+

Modified: vidalia/branches/hidden-services/src/vidalia/config/servicepage.h
===================================================================
--- vidalia/branches/hidden-services/src/vidalia/config/servicepage.h	2008-07-04 15:16:43 UTC (rev 2835)
+++ vidalia/branches/hidden-services/src/vidalia/config/servicepage.h	2008-07-06 12:03:36 UTC (rev 2836)
@@ -18,6 +18,8 @@
 #include <helpbrowser.h>
 #include "configpage.h"
 #include "ui_servicepage.h"
+#include "serviceauthorizationdata.h"
+#include "ipvalidator.h"
 
 class ServicePage : public ConfigPage
 {
@@ -33,19 +35,28 @@
   /** Loads the settings for this page */
   void load();
   /** Initialize the service table */
-  void initServiceTable(QMap<int, Service>* _services);
-
-private slots:
-  /** Called whenever the user clicks on the 'add' button. */
-  void addService();
-  /** Called whenever the user clicks on the 'remove' button. */
-  void removeService();
-  /** Called whenever the user clicks on the 'copy' button. */
-  void copyToClipboard();
-  /** Called whenever the user clicks on the 'browse' button. */
-  void browseDirectory();
-  /** Called whenever the user selects a different service. */
-  void serviceSelectionChanged();
+  void initServiceTable();
+  /** Initialize the service access table */
+  void initServiceAccessTable(QList<ServiceAuthorizationData> authdataList);
+  /** this method is called to ensure that all required fields are set
+  * before the saving starts.
+  * @return a boolean showing whether all required fields are set or not */
+  bool checkBeforeChanging();
+  /** this method merges the list of services received from Vidalia and Tor
+  * @return a list containing all services without double entries */
+  QList<Service> mergeServices(QList<Service> torServices,
+   QList<Service> vidaliaServices);
+  /** this method is called in order to validate the service authorization
+  *  string a user wants to store within vidalia
+  *  @return a QValidator::State signalling whether the string is valid or not*/
+  QValidator::State validateServiceAuth(QString authString);
+  /** this method is called to parse the client_keys file in order to
+  * get all users that had a authorization for the Service
+  * @return a list of all users found in client_keys*/
+  QList<UserAuthorizationData> parseClientKeys(QString dir);
+  /** this method creates the configuration string for tor including the
+   * user authorization*/
+  QString createUserAuthStringForTor(QList<UserAuthorizationData> users);
   /** Returns a list of services by parsing the configuration string given
    * by the Tor controller. */
   QList<Service> extractSingleServices(QString conf);
@@ -58,32 +69,71 @@
   bool isServicePublished(Service service, QList<Service> torServices);
   /** Returns true if all services have the required minimal configuration. */
   bool checkBeforeSaving(QList<Service> services);
+
+private slots:
+  /** Called whenever the user clicks on the 'add' button. */
+  void addService();
+  /** Called whenever the user clicks on the 'remove' button. */
+  void removeService();
+  /** Called whenever the user clicks on the 'copy' button. */
+  void copyToClipboard();
+  /** Called whenever the user clicks on the 'browse' button. */
+  void browseDirectory();
+  /** Called whenever the user selects a different service. */
+  void serviceSelectionChanged(QTableWidgetItem* current,
+   QTableWidgetItem * previous);
   /** Called when the user finished editing a cell and checks that only valid
    * values are set. */
   void valueChanged();
-  /** Called when the user checks the box for restricted access to hidden service*/
+  /** Called when the user checks the box to restrict access to hidden service*/
   void clientAuthChecked(int state);
+  /** Called when the user wants to add a client with authorization */
   void addClientAuthBtnClicked();
+  /** Called when the user wants to remove a client with authorization */
   void removeClientAuthBtnClicked();
+  /** Called when the user wants to copy the authorization of a client
+   * to the clipboard*/
   void copyClientAuthBtnClicked();
+  /** Called when the user wants to store authorization for a service*/
   void addServiceAuthBtnClicked();
+  /** Called when the user wants to remove authorization data for a service */
   void removeServiceAuthBtnClicked();
+  /** Called when the user wants to copy athorization data for a service to
+   * the clipboard*/
   void copyServiceAuthBtnClicked();
-  void authValueChanged();
+  /** Called when a value of the serviceAuthWidget is changed, to ensure only
+   * valid values*/
+  void clientAuthValueChanged();
+  /** Called when a value of the serviceAcceessWidget is changed, to ensure
+   * only valid values*/
+  void serviceAccessValueChanged();
+  /** Called whenever the user selects a different service access
+   * entry(Consumed Services)*/
+  void serviceAccessSelectionChanged();
+  /** Called whenever the user selects a different service authorization
+   * entry(Provided Services)*/
+  void serviceAuthSelectionChanged();
 
 private:
-  /** A TorControl object used to talk to Tor. */
-  TorControl* _torControl;
-  /** A TorSettings object used for saving/loading the Tor settings */
-  TorSettings *_torSettings;
+
   /** A ServiceSettings object used to load/save the services. */
   ServiceSettings* _serviceSettings;
   /** A QMap, mapping from the row number in the table to the service Entity */
   QMap<int, Service>* _services;
   /** A QList, consisting of all running services before vidalia starts */
   QMap<QString, Service>* _torServices;
+  /* a map mapping from the unique comment, to the auth data of a service*/
+  QMap<QString, ServiceAuthorizationData>* _consumedServices;
   /** Qt Designer generated object */
   Ui::ServicePage ui;
+  /** A QRegExpValidator to validate the identification of client auth(Id)
+   * and service auth(Id)*/
+  QRegExpValidator *_identificationValidator;
+  /** A QRegExpValidator to validate a onion address (base32, 16 chars
+   * +".onion"*/
+  QRegExpValidator* _onionAdressValidator;
+  /** A QRegExpValidator to validate a cookie(base64, 22 chars)*/
+  QRegExpValidator* _cookieValidator;
 };
 
 #endif

Modified: vidalia/branches/hidden-services/src/vidalia/config/servicepage.ui
===================================================================
--- vidalia/branches/hidden-services/src/vidalia/config/servicepage.ui	2008-07-04 15:16:43 UTC (rev 2835)
+++ vidalia/branches/hidden-services/src/vidalia/config/servicepage.ui	2008-07-06 12:03:36 UTC (rev 2836)
@@ -260,26 +260,6 @@
          </property>
          <layout class="QVBoxLayout" >
           <item>
-           <layout class="QHBoxLayout" >
-            <item>
-             <widget class="QLabel" name="label" >
-              <property name="sizePolicy" >
-               <sizepolicy vsizetype="Minimum" hsizetype="Preferred" >
-                <horstretch>0</horstretch>
-                <verstretch>0</verstretch>
-               </sizepolicy>
-              </property>
-              <property name="text" >
-               <string>Add client with (private only) comment:</string>
-              </property>
-             </widget>
-            </item>
-            <item>
-             <widget class="QLineEdit" name="privateCommentLineProvider" />
-            </item>
-           </layout>
-          </item>
-          <item>
            <layout class="QGridLayout" >
             <item rowspan="4" row="0" column="0" >
              <widget class="QTableWidget" name="serviceAuthWidget" >
@@ -306,14 +286,19 @@
               </property>
               <column>
                <property name="text" >
-                <string>Client Authorization String</string>
+                <string>Authorization String</string>
                </property>
               </column>
               <column>
                <property name="text" >
-                <string>Comment</string>
+                <string>Identification</string>
                </property>
               </column>
+              <column>
+               <property name="text" >
+                <string>Enabled</string>
+               </property>
+              </column>
              </widget>
             </item>
             <item row="0" column="1" >
@@ -421,7 +406,7 @@
          <item row="0" column="1" >
           <widget class="QLabel" name="label_4" >
            <property name="text" >
-            <string>Comment</string>
+            <string>Identification:</string>
            </property>
           </widget>
          </item>
@@ -436,21 +421,27 @@
        <item>
         <layout class="QGridLayout" >
          <item rowspan="4" row="0" column="0" >
-          <widget class="QTableWidget" name="tableWidget_2" >
+          <widget class="QTableWidget" name="serviceAccessWidget" >
            <property name="sizePolicy" >
             <sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
              <horstretch>0</horstretch>
              <verstretch>0</verstretch>
             </sizepolicy>
            </property>
+           <property name="selectionMode" >
+            <enum>QAbstractItemView::SingleSelection</enum>
+           </property>
+           <property name="selectionBehavior" >
+            <enum>QAbstractItemView::SelectRows</enum>
+           </property>
            <column>
             <property name="text" >
-             <string>Client Authorization String</string>
+             <string>Service Authorization String</string>
             </property>
            </column>
            <column>
             <property name="text" >
-             <string>Comment</string>
+             <string>Identification</string>
             </property>
            </column>
           </widget>
@@ -552,22 +543,38 @@
    </hints>
   </connection>
   <connection>
-   <sender>privateCommentLineProvider</sender>
+   <sender>commentLineAccess</sender>
    <signal>returnPressed()</signal>
-   <receiver>addClientAuthBtn</receiver>
-   <slot>click()</slot>
+   <receiver>authLineAccess</receiver>
+   <slot>setFocus()</slot>
    <hints>
     <hint type="sourcelabel" >
-     <x>434</x>
-     <y>350</y>
+     <x>480</x>
+     <y>120</y>
     </hint>
     <hint type="destinationlabel" >
-     <x>607</x>
-     <y>383</y>
+     <x>171</x>
+     <y>120</y>
     </hint>
    </hints>
   </connection>
   <connection>
+   <sender>addServiceAuthBtn</sender>
+   <signal>clicked()</signal>
+   <receiver>authLineAccess</receiver>
+   <slot>setFocus()</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>618</x>
+     <y>153</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>171</x>
+     <y>120</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
    <sender>commentLineAccess</sender>
    <signal>returnPressed()</signal>
    <receiver>addServiceAuthBtn</receiver>

Modified: vidalia/branches/hidden-services/src/vidalia/config/servicesettings.cpp
===================================================================
--- vidalia/branches/hidden-services/src/vidalia/config/servicesettings.cpp	2008-07-04 15:16:43 UTC (rev 2835)
+++ vidalia/branches/hidden-services/src/vidalia/config/servicesettings.cpp	2008-07-06 12:03:36 UTC (rev 2836)
@@ -12,6 +12,7 @@
 #include <stringutil.h>
 #include "servicesettings.h"
 #include "torsettings.h"
+#include <torcontrol.h>
 
 /* Service Settings */
 #define SETTING_SERVICE_VIRTUAL_PORT "Service/VirtualPort"
@@ -19,14 +20,15 @@
 #define SETTING_SERVICE_PHYSICAL_ADDRESS "Service/ServicePhysicalAddress"
 #define SETTING_SERVICE_ENABLED "Service/Enabled"
 #define SETTING_TOR_SERVICES "Service/Services"
+#define SETTING_TOR_CONSUMED_SERVICES "Service/ConsumedServices"
 
 /** Constructor.
  * \param torControl a TorControl object used to read and apply the Service
  * configuration settings.
  */
 ServiceSettings::ServiceSettings(TorControl *torControl)
+: AbstractTorSettings("Service", torControl)
 {
-  _torControl = torControl;
   setDefault(SETTING_SERVICE_VIRTUAL_PORT , 0);
   setDefault(SETTING_SERVICE_PHYSICAL_ADDRESS, "127.0.0.1:0");
   setDefault(SETTING_SERVICE_ENABLED, "true");
@@ -46,6 +48,13 @@
   setValue(SETTING_TOR_SERVICES, serviceList);
 }
 
+bool
+ServiceSettings::apply(QString *errmsg)
+{
+  //dummy
+  return true;
+}
+
 /** Get  serialised ServiceList */
 ServiceList
 ServiceSettings::getServices()
@@ -58,7 +67,7 @@
 
   stringList = value(SETTING_TOR_SERVICES).toStringList();
   foreach (QString s, stringList) {
-  	QList<User> users;
+    QList<UserAuthorizationData> users;
     QStringList skippedList = s.split("#");
     address = skippedList.first();
     skippedList.removeFirst();
@@ -78,13 +87,13 @@
     //for each user parse the authorization data
     foreach(QString user, skippedList)
     {
-      if(user.contains('*', Qt::CaseSensitive)) 
+      if(user.contains('*', Qt::CaseSensitive))
       {
         QStringList secondsplit = user.split("*");
         QString comment = secondsplit.first();
         secondsplit.removeFirst();
         QString authdata = secondsplit.first();
-        User u(comment, authdata);
+        UserAuthorizationData u(comment, authdata);
         users.push_back(u);
       }
     }
@@ -96,6 +105,53 @@
   return services;
 }
 
+/** Set ServiceAthorizationData List to serialze it*/
+void
+ServiceSettings::setServiceAuthorizationData(
+ QList<ServiceAuthorizationData> list)
+{
+  QStringList serviceAuthdataList;
+  QString torConfString;
+  if(list.size() > 0) {
+    foreach(ServiceAuthorizationData tempService, list) {
+      serviceAuthdataList << tempService.toString();
+      //HidServAuth service-name client-key descriptor-cookie
+      torConfString.append(tempService.identification());
+      QStringList strList = tempService.authdata().split(" ");
+      torConfString.append(" "+strList.first().trimmed());
+      strList.removeFirst();
+      torConfString.append(" "+strList.first().trimmed());
+            torControl()->setConf("HidServAuth", torConfString);
+    }
+  }
+  setValue(SETTING_TOR_CONSUMED_SERVICES, serviceAuthdataList);
+}
+
+/** Returns a list containing all ServiceAthorizationData */
+QList<ServiceAuthorizationData>
+ServiceSettings::getServiceAuthorizationData()
+{
+  QString authdata, comment;
+  QList<ServiceAuthorizationData> authdataList;
+  QStringList stringList;
+  stringList = value(SETTING_TOR_CONSUMED_SERVICES).toStringList();
+  foreach (QString s, stringList) {
+    QStringList skippedList = s.split("#");
+    foreach(QString service, skippedList) {
+      if(service.contains('*', Qt::CaseSensitive)) {
+        QStringList skip2List = service.split("*");
+        authdata = skip2List.first();
+        skip2List.removeFirst();
+        comment = skip2List.first();
+        skip2List.removeFirst();
+        ServiceAuthorizationData s(authdata, comment);
+        authdataList << s;
+      }
+    }
+  }
+  return authdataList;
+}
+
 /** Returns the virtual port for a specififc service*/
 QString
 ServiceSettings::getVirtualPort()
@@ -159,7 +215,7 @@
 QString
 ServiceSettings::getHiddenServiceDirectories()
 {
-  QString value =  _torControl->getHiddenServiceConf("hiddenserviceoptions");
+  QString value =  torControl()->getHiddenServiceConf("hiddenserviceoptions");
   return value;
 }
 
@@ -168,15 +224,15 @@
 void
 ServiceSettings::applyServices(QString value, QString *errmsg)
 {
-  _torControl->setConf(value, errmsg);
-  _torControl->saveConf(errmsg);
+  torControl()->setConf(value, errmsg);
+  torControl()->saveConf(errmsg);
 }
 
 /** Unpublish all HiddenServices */
 void
 ServiceSettings::unpublishAllServices(QString *errmsg)
 {
-  _torControl->resetConf("HiddenServiceDir", errmsg);
-  _torControl->saveConf(errmsg);
+  torControl()->resetConf("HiddenServiceDir", errmsg);
+  torControl()->saveConf(errmsg);
 }
 

Modified: vidalia/branches/hidden-services/src/vidalia/config/servicesettings.h
===================================================================
--- vidalia/branches/hidden-services/src/vidalia/config/servicesettings.h	2008-07-04 15:16:43 UTC (rev 2835)
+++ vidalia/branches/hidden-services/src/vidalia/config/servicesettings.h	2008-07-06 12:03:36 UTC (rev 2836)
@@ -13,17 +13,23 @@
 
 #include <torcontrol.h>
 #include <servicelist.h>
-#include <user.h>
-#include "vidaliasettings.h"
+#include <userauthorizationdata.h>
+#include <serviceauthorizationdata.h>
+#include "abstracttorsettings.h"
 #include "exitpolicy.h"
 
-class ServiceSettings : private VidaliaSettings
+class ServiceSettings : public AbstractTorSettings
 {
+  Q_OBJECT
 
 public:
 
   /** Constructor */
   ServiceSettings(TorControl *torControl);
+  /** Applies the current network configuration settings to Tor. If
+   *  * <b>errmsg</b> is specified and an error occurs while applying the
+   *  settings, it will be set to a string describing the error. */
+  bool apply(QString *errmsg = 0);
   /** Returns the service port for a specififc service*/
   QString getVirtualPort();
   /** Set the service port for a specififc service*/
@@ -44,6 +50,10 @@
   ServiceList getServices();
   /** Set ServiceList to serialise it */
   void setServices(ServiceList services);
+  /** Set ServiceAthorizationData List to serialze it*/
+  void setServiceAuthorizationData(QList<ServiceAuthorizationData> list);
+  /** Returns a list containing all ServiceAthorizationData */
+  QList<ServiceAuthorizationData> getServiceAuthorizationData();
   /** Get Service Directories */
   QString getHiddenServiceDirectories();
   /** Set all services the user wants to start and send it to the
@@ -52,10 +62,6 @@
   /** Unpublish all services */
   void unpublishAllServices(QString *errmsg);
 
-private:
-
-  /** A TorControl object used to talk to Tor. */
-  TorControl* _torControl;
 };
 
 #endif

Deleted: vidalia/branches/hidden-services/src/vidalia/config/user.cpp

Deleted: vidalia/branches/hidden-services/src/vidalia/config/user.h

Added: vidalia/branches/hidden-services/src/vidalia/config/userauthorizationdata.cpp
===================================================================
--- vidalia/branches/hidden-services/src/vidalia/config/userauthorizationdata.cpp	                        (rev 0)
+++ vidalia/branches/hidden-services/src/vidalia/config/userauthorizationdata.cpp	2008-07-06 12:03:36 UTC (rev 2836)
@@ -0,0 +1,28 @@
+/*
+**  This file is part of Vidalia, and is subject to the license terms in the
+**  LICENSE file, found in the top level directory of this distribution. If you
+**  did not receive the LICENSE file with this file, you may obtain it from the
+**  Vidalia source package distributed by the Vidalia Project at
+**  http://www.vidalia-project.net/. No part of Vidalia, including this file,
+**  may be copied, modified, propagated, or distributed except according to the
+**  terms described in the LICENSE file.
+*/
+
+#include "userauthorizationdata.h"
+
+UserAuthorizationData::UserAuthorizationData()
+{
+}
+
+/** Constructor to create a new User with initial settings */
+UserAuthorizationData::UserAuthorizationData(QString authdata, QString identification):
+ AbstractAuthorizationData(authdata, identification)
+{
+}
+
+/* Sets the enabled value of a specific user */
+void UserAuthorizationData::setEnabled(bool enabled)
+{
+  _enabled = enabled;;
+}
+

Added: vidalia/branches/hidden-services/src/vidalia/config/userauthorizationdata.h
===================================================================
--- vidalia/branches/hidden-services/src/vidalia/config/userauthorizationdata.h	                        (rev 0)
+++ vidalia/branches/hidden-services/src/vidalia/config/userauthorizationdata.h	2008-07-06 12:03:36 UTC (rev 2836)
@@ -0,0 +1,38 @@
+/*
+**  This file is part of Vidalia, and is subject to the license terms in the
+**  LICENSE file, found in the top level directory of this distribution. If you
+**  did not receive the LICENSE file with this file, you may obtain it from the
+**  Vidalia source package distributed by the Vidalia Project at
+**  http://www.vidalia-project.net/. No part of Vidalia, including this file,
+**  may be copied, modified, propagated, or distributed except according to the
+**  terms described in the LICENSE file.
+*/
+
+#ifndef USERAUTHORIZATIONDATA_H_
+#define USERAUTHORIZATIONDATA_H_
+
+#include <QString>
+#include <QMetaType>
+
+#include "abstractauthorizationdata.h"
+
+class UserAuthorizationData : public AbstractAuthorizationData
+{
+public:
+
+  UserAuthorizationData();
+  /** Constructor to create a new Service with initial settings */
+  UserAuthorizationData(QString authdata, QString identification);
+  /** Returns the enabled value of a specific user */
+  bool enabled() const { return _enabled; }
+  /** Sets the enabled value of a specific user */
+  void setEnabled(bool enabled);
+
+private:
+  /** shows whether a user is enabled for the service or not. */
+  bool _enabled;
+
+};
+Q_DECLARE_METATYPE(UserAuthorizationData);
+#endif /*UserAuthorizationData_H_*/
+