From owner-p4-projects@FreeBSD.ORG Mon Aug 20 10:44:08 2007 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id AB5D016A420; Mon, 20 Aug 2007 10:44:07 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 6AFFC16A41B for ; Mon, 20 Aug 2007 10:44:07 +0000 (UTC) (envelope-from andrew@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 597C413C45A for ; Mon, 20 Aug 2007 10:44:07 +0000 (UTC) (envelope-from andrew@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id l7KAi7pc037621 for ; Mon, 20 Aug 2007 10:44:07 GMT (envelope-from andrew@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id l7KAi7SW037615 for perforce@freebsd.org; Mon, 20 Aug 2007 10:44:07 GMT (envelope-from andrew@freebsd.org) Date: Mon, 20 Aug 2007 10:44:07 GMT Message-Id: <200708201044.l7KAi7SW037615@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to andrew@freebsd.org using -f From: Andrew Turner To: Perforce Change Reviews Cc: Subject: PERFORCE change 125399 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 20 Aug 2007 10:44:08 -0000 http://perforce.freebsd.org/chv.cgi?CH=125399 Change 125399 by andrew@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 @@ - + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK @@ -110,34 +110,27 @@ 5 5 - + True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Restart + Connect 0 - - 2 - 2 - 3 - - + True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Remove + Disconnect 0 1 2 - 1 - 2 @@ -155,28 +148,35 @@ - + True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Disconnect + Remove 0 1 2 + 1 + 2 - + True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Connect + Restart 0 + + 2 + 2 + 3 + @@ -276,27 +276,34 @@ 3 10 - + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Computer's description +This is a Human redable +name for the computer + + + + True + True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Socket location -Leave blank for -the default socket - 2 - 3 + 1 + 2 - + True + True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Computer's name -leave blank for the -local computer + 1 + 2 1 2 @@ -315,37 +322,109 @@ - + True - True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Computer's name +leave blank for the +local computer - 1 - 2 1 2 - + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Socket location +Leave blank for +the default socket + + + 2 + 3 + + + + + 1 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + GTK_BUTTONBOX_END + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-save + True + 0 + + + + True True + True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-cancel + True + 0 - 1 - 2 + 1 + + + False + GTK_PACK_END + + + + + + + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 5 + GTK_WIN_POS_CENTER_ON_PARENT + GDK_WINDOW_TYPE_HINT_DIALOG + False + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 2 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Password: + GTK_JUSTIFY_RIGHT + + - + True + True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Computer's description -This is a Human redable -name for the computer + False + True + + 1 + @@ -353,23 +432,23 @@ - + True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK GTK_BUTTONBOX_END - + True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - gtk-save + gtk-ok True 0 - + True True True ==== //depot/projects/soc2007/andrew-update/frontend/facund/call.py#3 (text+ko) ==== @@ -65,7 +65,11 @@ def __str__(self): return "%s" \ - % (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 = ""; + if (salt == 0) { + str = strdup(""); + } else { + asprintf(&str, "", + salt); + } + if (str == NULL) { + return -1; + } facund_send(conn, str, strlen(str)); + free(str); return 0; }