PERFORCE change 125399 for review
Andrew Turner
andrew at FreeBSD.org
Mon Aug 20 03:44:08 PDT 2007
http://perforce.freebsd.org/chv.cgi?CH=125399
Change 125399 by andrew at andrew_hermies on 2007/08/20 10:43:08
Send a salt to the client to be used to check the password sent is correct
Add an authenticate call. It accepts a password in the form sha256(sha256(password) + salt). Only when this is correct does it enable the other calls
Ass a password dialog when connecting
Set the correct attributes to a response when reading it in in the front end
Affected files ...
.. //depot/projects/soc2007/andrew-update/backend/facund-be.c#26 edit
.. //depot/projects/soc2007/andrew-update/backend/freebsd-config-control.conf#2 edit
.. //depot/projects/soc2007/andrew-update/frontend/facund-fe.glade#7 edit
.. //depot/projects/soc2007/andrew-update/frontend/facund/call.py#3 edit
.. //depot/projects/soc2007/andrew-update/frontend/facund/computer.py#15 edit
.. //depot/projects/soc2007/andrew-update/frontend/facund/gui/main_window.py#15 edit
.. //depot/projects/soc2007/andrew-update/frontend/facund/network/__init__.py#15 edit
.. //depot/projects/soc2007/andrew-update/lib/facund_connection.h#5 edit
.. //depot/projects/soc2007/andrew-update/lib/facund_server.c#13 edit
Differences ...
==== //depot/projects/soc2007/andrew-update/backend/facund-be.c#26 (text+ko) ====
@@ -74,6 +74,8 @@
static struct facund_response *facund_read_type_directory(const char *,
const struct facund_object *, const char ***, int *, int *);
+static struct facund_response *facund_call_authenticate(const char *,
+ struct facund_object *);
static struct facund_response *facund_call_ping(const char *,
struct facund_object *);
static struct facund_response *facund_get_directories(const char *,
@@ -123,7 +125,8 @@
static unsigned int watched_db_count = 0;
static struct fbsd_update_db *watched_db = NULL;
-struct utsname facund_uname;
+static struct utsname facund_uname;
+static char *password_hash = NULL;
/*
* Decodes the data in a line from the tag file
@@ -517,6 +520,8 @@
facund_comms_in_loop = 0;
}
+static long facund_salt = 0;
+
static void *
do_communication(void *data)
{
@@ -534,7 +539,11 @@
/* We are now in the loop. This will change on SIGPIPE */
facund_comms_in_loop = 1;
- if(facund_server_start(conn) == -1) {
+ assert(facund_salt == 0);
+ do {
+ facund_salt = random();
+ } while (facund_salt == 0);
+ if(facund_server_start(conn, facund_salt) == -1) {
if (facund_in_loop != 0) {
/*
* When we are not quiting tell
@@ -545,8 +554,10 @@
}
break;
}
- if (facund_comms_in_loop == 0)
+ if (facund_comms_in_loop == 0) {
+ facund_salt = 0;
continue;
+ }
while(ret == 0) {
ret = facund_server_get_request(conn);
@@ -559,6 +570,7 @@
if (facund_comms_in_loop == 0)
break;
}
+ facund_salt = 0;
if (facund_comms_in_loop == 0)
continue;
@@ -573,6 +585,40 @@
}
static struct facund_response *
+facund_call_authenticate(const char *id, struct facund_object *obj)
+{
+ char *buf, sum[65];
+
+ if (facund_salt == 0) {
+ return facund_response_new(id, 1, "Already authenticated",NULL);
+ }
+ if (facund_object_get_type(obj) != FACUND_STRING) {
+ return facund_response_new(id, 1, "Incorrect Data", NULL);
+ }
+
+ /* Check the password */
+ asprintf(&buf, "%s%ld", password_hash, facund_salt);
+ SHA256_Data(buf, strlen(buf), sum);
+ free(buf);
+ printf("%s\n%s\n\n", sum, facund_object_get_string(obj));
+ if (strcmp(sum, facund_object_get_string(obj)) != 0) {
+ return facund_response_new(id, 1, "Incorrect Password", NULL);
+ }
+
+ /* Add the callbacks for each call */
+ facund_server_add_call("ping", facund_call_ping);
+ facund_server_add_call("get_directories", facund_get_directories);
+ facund_server_add_call("list_updates", facund_call_list_updates);
+ facund_server_add_call("list_installed", facund_call_list_installed);
+ facund_server_add_call("install_patches", facund_call_install_patches);
+ facund_server_add_call("rollback_patches",facund_call_rollback_patches);
+ facund_server_add_call("get_services", facund_call_get_services);
+ facund_server_add_call("restart_services",facund_call_restart_services);
+
+ return facund_response_new(id, 0, "No Error", NULL);
+}
+
+static struct facund_response *
facund_call_ping(const char *id, struct facund_object *obj __unused)
{
struct facund_response *resp;
@@ -1321,6 +1367,14 @@
errx(1, "Malloc failed");
}
+ password_hash = property_find(config_data, "password");
+ if (password_hash != NULL) {
+ password_hash = strdup(password_hash);
+ if (password_hash == NULL) {
+ errx(1, "Malloc failed");
+ }
+ }
+
properties_free(config_data);
}
@@ -1347,15 +1401,8 @@
sizeof facund_uname.release);
}
- /* Add the callbacks for each call */
- facund_server_add_call("ping", facund_call_ping);
- facund_server_add_call("get_directories", facund_get_directories);
- facund_server_add_call("list_updates", facund_call_list_updates);
- facund_server_add_call("list_installed", facund_call_list_installed);
- facund_server_add_call("install_patches", facund_call_install_patches);
- facund_server_add_call("rollback_patches",facund_call_rollback_patches);
- facund_server_add_call("get_services", facund_call_get_services);
- facund_server_add_call("restart_services",facund_call_restart_services);
+ /* Only allow people to authenticate to begin with */
+ facund_server_add_call("authenticate", facund_call_authenticate);
pthread_create(&update_thread, NULL, look_for_updates, NULL);
pthread_create(&comms_thread, NULL, do_communication, conn);
==== //depot/projects/soc2007/andrew-update/backend/freebsd-config-control.conf#2 (text+ko) ====
@@ -1,1 +1,5 @@
base_dirs = /
+
+; The password is "password". Change this with:
+; ecgo -n password | sha256
+password = 5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8
==== //depot/projects/soc2007/andrew-update/frontend/facund-fe.glade#7 (text+ko) ====
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
-<!--Generated with glade3 3.2.2 on Mon Aug 20 10:28:13 2007 by andrew at hermies.int.fubar.geek.nz-->
+<!--Generated with glade3 3.2.2 on Mon Aug 20 20:59:08 2007 by andrew at hermies.int.fubar.geek.nz-->
<glade-interface>
<widget class="GtkWindow" id="facundWindow">
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
@@ -110,34 +110,27 @@
<property name="column_spacing">5</property>
<property name="row_spacing">5</property>
<child>
- <widget class="GtkButton" id="restartButton">
+ <widget class="GtkButton" id="connectButton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="label" translatable="yes">Restart</property>
+ <property name="label" translatable="yes">Connect</property>
<property name="response_id">0</property>
</widget>
- <packing>
- <property name="right_attach">2</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- </packing>
</child>
<child>
- <widget class="GtkButton" id="deinstallButton">
+ <widget class="GtkButton" id="disconnectButton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="label" translatable="yes">Remove</property>
+ <property name="label" translatable="yes">Disconnect</property>
<property name="response_id">0</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
</packing>
</child>
<child>
@@ -155,28 +148,35 @@
</packing>
</child>
<child>
- <widget class="GtkButton" id="disconnectButton">
+ <widget class="GtkButton" id="deinstallButton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="label" translatable="yes">Disconnect</property>
+ <property name="label" translatable="yes">Remove</property>
<property name="response_id">0</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
</packing>
</child>
<child>
- <widget class="GtkButton" id="connectButton">
+ <widget class="GtkButton" id="restartButton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="label" translatable="yes">Connect</property>
+ <property name="label" translatable="yes">Restart</property>
<property name="response_id">0</property>
</widget>
+ <packing>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ </packing>
</child>
</widget>
<packing>
@@ -276,27 +276,34 @@
<property name="column_spacing">3</property>
<property name="row_spacing">10</property>
<child>
- <widget class="GtkLabel" id="label2">
+ <widget class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="label" translatable="yes">Computer's description
+This is a Human redable
+name for the computer</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="computerNameEntry">
<property name="visible">True</property>
+ <property name="can_focus">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="label" translatable="yes">Socket location
-Leave blank for
-the default socket</property>
</widget>
<packing>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
</packing>
</child>
<child>
- <widget class="GtkLabel" id="label1">
+ <widget class="GtkEntry" id="computerEntry">
<property name="visible">True</property>
+ <property name="can_focus">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="label" translatable="yes">Computer's name
-leave blank for the
-local computer</property>
</widget>
<packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
@@ -315,37 +322,109 @@
</packing>
</child>
<child>
- <widget class="GtkEntry" id="computerEntry">
+ <widget class="GtkLabel" id="label1">
<property name="visible">True</property>
- <property name="can_focus">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="label" translatable="yes">Computer's name
+leave blank for the
+local computer</property>
</widget>
<packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
- <widget class="GtkEntry" id="computerNameEntry">
+ <widget class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="label" translatable="yes">Socket location
+Leave blank for
+the default socket</property>
+ </widget>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area1">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+ <child>
+ <widget class="GtkButton" id="newConnectionSave">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="label" translatable="yes">gtk-save</property>
+ <property name="use_stock">True</property>
+ <property name="response_id">0</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkButton" id="newConnectionCancel">
<property name="visible">True</property>
<property name="can_focus">True</property>
+ <property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="label" translatable="yes">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="response_id">0</property>
</widget>
<packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
+ <property name="position">1</property>
</packing>
</child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <widget class="GtkDialog" id="passwordDialog">
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="border_width">5</property>
+ <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="has_separator">False</property>
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox2">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="spacing">2</property>
+ <child>
+ <widget class="GtkHBox" id="hbox1">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <child>
+ <widget class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="label" translatable="yes">Password:</property>
+ <property name="justify">GTK_JUSTIFY_RIGHT</property>
+ </widget>
+ </child>
<child>
- <widget class="GtkLabel" id="label3">
+ <widget class="GtkEntry" id="passwordEntry">
<property name="visible">True</property>
+ <property name="can_focus">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="label" translatable="yes">Computer's description
-This is a Human redable
-name for the computer</property>
+ <property name="visibility">False</property>
+ <property name="activates_default">True</property>
</widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
</child>
</widget>
<packing>
@@ -353,23 +432,23 @@
</packing>
</child>
<child internal-child="action_area">
- <widget class="GtkHButtonBox" id="dialog-action_area1">
+ <widget class="GtkHButtonBox" id="dialog-action_area2">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="layout_style">GTK_BUTTONBOX_END</property>
<child>
- <widget class="GtkButton" id="newConnectionSave">
+ <widget class="GtkButton" id="passwordOkButton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="label" translatable="yes">gtk-save</property>
+ <property name="label" translatable="yes">gtk-ok</property>
<property name="use_stock">True</property>
<property name="response_id">0</property>
</widget>
</child>
<child>
- <widget class="GtkButton" id="newConnectionCancel">
+ <widget class="GtkButton" id="passwordCancelButton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
==== //depot/projects/soc2007/andrew-update/frontend/facund/call.py#3 (text+ko) ====
@@ -65,7 +65,11 @@
def __str__(self):
return "<response id=\"%s\" message=\"%s\" code=\"%s\">%s</response>" \
- % (self.__id, self.__message, self.__code, str(self.__data))
+ % (self.__id, self.__message, self.__code,
+ str(self.__data or ''))
def getData(self):
return self.__data
+
+ def getCode(self):
+ return self.__code
==== //depot/projects/soc2007/andrew-update/frontend/facund/computer.py#15 (text+ko) ====
@@ -24,8 +24,9 @@
# SUCH DAMAGE.
#
+import facund.network
+import hashlib
import socket
-import facund.network
import threading
import types
@@ -174,7 +175,7 @@
return call.getResponse()
- def connect(self):
+ def connect(self, password):
'''Connects to the remote computer'''
if self.__connection is not None:
return
@@ -194,6 +195,22 @@
self.__connection.startLock.acquire()
self.__connection.startLock.release()
+ # Authenticate with the server
+ salt = self.__connection.getSalt()
+ pass_hash = hashlib.sha256(password).hexdigest()
+ pass_hash = pass_hash + str(salt)
+ pass_hash = hashlib.sha256(pass_hash).hexdigest()
+ pass_hash = facund.String(pass_hash)
+ call = facund.Call("authenticate", pass_hash)
+ self.__connection.doCall(call)
+ call.acquireLock()
+ call.releaseLock()
+ # Disconnect if we failed to authenticate
+ if call.getResponse().getCode() != 0:
+ print call.getResponse().getCode()
+ self.disconnect()
+ return
+
# Get a list of directories the server offers
call = facund.Call("get_directories", None)
self.__connection.doCall(call)
@@ -202,6 +219,7 @@
dirs = call.getResponse().getData().getData()
for dir in dirs:
self.addDir(dir.getData())
+
except socket.error:
print "Couldn't connect to %s " % (self.__host or self.__socket)
del self.__connection
==== //depot/projects/soc2007/andrew-update/frontend/facund/gui/main_window.py#15 (text+ko) ====
@@ -60,6 +60,7 @@
menuItem.connect('activate', self.onQuit)
self.__newConnectionDialog = None
+ self.__passwordDialog = None
# Connect the signals to the new connection dialog box
button = self.__xml.get_widget('newConnectionCancel')
@@ -68,6 +69,13 @@
button = self.__xml.get_widget('newConnectionSave')
button.connect('clicked', self.connectionSave)
+ # Connect the signals to the password dialog
+ button = self.__xml.get_widget('passwordOkButton')
+ button.connect('clicked', self.connectionStart)
+
+ button = self.__xml.get_widget('passwordCancelButton')
+ button.connect('clicked', self.connectionCancel)
+
def onQuit(self, data):
self.__controller.shutdown()
@@ -186,17 +194,13 @@
def onConnectClick(self, widget):
'''Signal handler for the connect button'''
- #treeView = self.__xml.get_widget('computerView')
- computer = self.__controller.getCurrentComputer()
- computer.connect()
- self.setConnected(computer.getConnectionStatus())
- self.__computerTreeModel.populateComputer(computer)
+ self.__passwordDialog = self.__xml.get_widget('passwordDialog')
+ self.__passwordDialog.show()
self.setInstallable(False, False)
def onDisconnectClick(self, widget):
'''Signal handler for the connect button'''
- #treeView = self.__xml.get_widget('computerView')
computer = self.__controller.getCurrentComputer()
computer.disconnect()
self.setConnected(computer.getConnectionStatus())
@@ -205,6 +209,22 @@
# Disable the install/remove buttons
self.setInstallable(False, False)
+ def connectionStart(self, widget):
+ password = self.__xml.get_widget('passwordEntry').get_text()
+
+ computer = self.__controller.getCurrentComputer()
+ computer.connect(password)
+ self.setConnected(computer.getConnectionStatus())
+ self.__computerTreeModel.populateComputer(computer)
+
+ self.connectionCancel(widget)
+
+ def connectionCancel(self, widget):
+ self.__passwordDialog.hide()
+ self.__passwordDialog = None
+
+ self.__xml.get_widget('passwordEntry').set_text('')
+
def onInstallClick(self, widget):
dir = self.__controller.getCurrentDirectory()
self.__controller.installUpdates((dir.getName(), 'base'))
==== //depot/projects/soc2007/andrew-update/frontend/facund/network/__init__.py#15 (text+ko) ====
@@ -112,7 +112,6 @@
pass
def doCall(self, call):
- print call.getID()
call.acquireLock()
self.__calls[str(call.getID())] = call
self.send(call.getCall())
@@ -123,6 +122,9 @@
def recv(self, len):
return self.__connection.read(len)
+ def getSalt(self):
+ return self.__salt
+
def interact(self):
'''Reads data from the connection and passes it to the
XML parser'''
@@ -136,8 +138,6 @@
return False
def startElement(self, name, attributes):
- print "> " + name + " " + str(attributes.items())
-
if name == "data":
data_type = None
data = None
@@ -166,23 +166,24 @@
self.__responseMessage = None
self.__responseCode = None
- for attr in attributes.items():
- if attr[0] == "id":
- self.__responseID = int(attr[1])
- elif attr[0] == "code":
- print self.__responseCode
- elif attr[0] == "message":
- self.__responseMessage = str(attr[1])
+ for name, value in attributes.items():
+ if name == "id":
+ self.__responseID = int(value)
+ elif name == "code":
+ self.__responseCode = int(value)
+ elif name == "message":
+ self.__responseMessage = str(value)
else:
print attr
elif name == "facund-server":
+ for name, value in attributes.items():
+ if name == 'salt':
+ self.__salt = int(value)
self.__connected_lock.acquire()
self.startLock.release()
def endElement(self, name):
- print "< " + name
-
if name == "data":
data = self.__data.getParent()
if data is not None:
@@ -191,7 +192,7 @@
elif name == "response":
response = facund.Response(self.__responseID,
- self.__responseMessage, self.__responseCode,
+ self.__responseCode, self.__responseMessage,
self.__data)
# TODO: Check this is a valid item
==== //depot/projects/soc2007/andrew-update/lib/facund_connection.h#5 (text+ko) ====
@@ -43,7 +43,7 @@
void facund_close(struct facund_conn *);
/* Server specific functions */
-int facund_server_start(struct facund_conn *);
+int facund_server_start(struct facund_conn *, long);
int facund_server_finish(struct facund_conn *);
int facund_server_get_request(struct facund_conn *);
==== //depot/projects/soc2007/andrew-update/lib/facund_server.c#13 (text+ko) ====
@@ -55,9 +55,9 @@
* next it replys with the server start and returns
*/
int
-facund_server_start(struct facund_conn *conn)
+facund_server_start(struct facund_conn *conn, long salt)
{
- const char *str;
+ char *str;
conn->close = 0;
conn->parser = XML_ParserCreate(NULL);
@@ -72,8 +72,17 @@
facund_server_end_tag);
XML_SetCharacterDataHandler(conn->parser, facund_server_text);
- str = "<facund-server version=\"0\">";
+ if (salt == 0) {
+ str = strdup("<facund-server version=\"0\">");
+ } else {
+ asprintf(&str, "<facund-server version=\"0\" salt=\"%ld\">",
+ salt);
+ }
+ if (str == NULL) {
+ return -1;
+ }
facund_send(conn, str, strlen(str));
+ free(str);
return 0;
}
More information about the p4-projects
mailing list