Patch for CVE-2008-2941

Fixes parser fragility: original code expects only strings or numbers as
the input values, but not both.  And hpssd client has the full control
on the input data, so when number is tried to be transformed as string
(by calling lower() method, for example) the unhandled exception
terminates the daemon.

Based on: https://bugzilla.redhat.com/attachment.cgi?id=312881

--- hpssd.py.orig	2008-11-23 22:41:08.000000000 +0300
+++ hpssd.py	2008-11-23 22:57:51.000000000 +0300
@@ -203,7 +203,7 @@
                 log.debug(self.out_buffer)
                 return True
 
-            msg_type = self.fields.get('msg', 'unknown').lower()
+            msg_type = str(self.fields.get('msg', 'unknown')).lower()
             log.debug("Handling: %s %s %s" % ("*"*20, msg_type, "*"*20))
             log.debug(repr(self.in_buffer))
 
@@ -260,9 +260,9 @@
 
 
     def handle_getvalue(self):
-        device_uri = self.fields.get('device-uri', '').replace('hpfax:', 'hp:')
+        device_uri = str(self.fields.get('device-uri', '')).replace('hpfax:', 'hp:')
         value = ''
-        key = self.fields.get('key', '')
+        key = str(self.fields.get('key', ''))
         result_code = self.__checkdevice(device_uri)
 
         if result_code == ERROR_SUCCESS:
@@ -274,9 +274,9 @@
         self.out_buffer = buildResultMessage('GetValueResult', value, result_code)
 
     def handle_setvalue(self):
-        device_uri = self.fields.get('device-uri', '').replace('hpfax:', 'hp:')
-        key = self.fields.get('key', '')
-        value = self.fields.get('value', '')
+        device_uri = str(self.fields.get('device-uri', '')).replace('hpfax:', 'hp:')
+        key = str(self.fields.get('key', ''))
+        value = str(self.fields.get('value', ''))
         result_code = self.__checkdevice(device_uri)
 
         if result_code == ERROR_SUCCESS:    
@@ -285,7 +285,7 @@
         self.out_buffer = buildResultMessage('SetValueResult', None, ERROR_SUCCESS)
 
     def handle_queryhistory(self):
-        device_uri = self.fields.get('device-uri', '').replace('hpfax:', 'hp:')
+        device_uri = str(self.fields.get('device-uri', '')).replace('hpfax:', 'hp:')
         payload = ''
         result_code = self.__checkdevice(device_uri)
 
@@ -305,8 +305,8 @@
 
     # EVENT
     def handle_registerguievent(self):
-        username = self.fields.get('username', '')
-        typ = self.fields.get('type', 'unknown')
+        username = str(self.fields.get('username', ''))
+        typ = str(self.fields.get('type', 'unknown'))
         self.typ = typ
         self.username = username
         self.send_events = True
@@ -314,13 +314,13 @@
 
     # EVENT
     def handle_unregisterguievent(self):
-        username = self.fields.get('username', '')
+        username = str(self.fields.get('username', ''))
         self.send_events = False
 
 
     def handle_test_email(self):
         result_code = ERROR_SUCCESS
-        username = self.fields.get('username', prop.username)
+        username = str(self.fields.get('username', prop.username))
         message = device.queryString('email_test_message')
         subject = device.queryString('email_test_subject')
         result_code = self.sendEmail(username, subject, message, True)
@@ -343,11 +343,14 @@
 
     # sent by hpfax: to indicate the start of a complete fax rendering job
     def handle_hpfaxbegin(self):
-        username = self.fields.get('username', prop.username)
-        job_id = self.fields.get('job-id', 0)
-        printer_name = self.fields.get('printer', '')
-        device_uri = self.fields.get('device-uri', '').replace('hp:', 'hpfax:')
-        title = self.fields.get('title', '')
+        username = str(self.fields.get('username', prop.username))
+        try:
+            job_id = int(self.fields.get('job-id', 0))
+        except ValueError:
+            job_id = 0
+        printer_name = str(self.fields.get('printer', ''))
+        device_uri = str(self.fields.get('device-uri', '')).replace('hp:', 'hpfax:')
+        title = str(self.fields.get('title', ''))
 
         log.debug("Creating data store for %s:%d" % (username, job_id))
         fax_file[(username, job_id)] = tempfile.NamedTemporaryFile(prefix="hpfax")
@@ -360,8 +363,11 @@
 
     # sent by hpfax: to transfer completed fax rendering data
     def handle_hpfaxdata(self):
-        username = self.fields.get('username', prop.username)
-        job_id = self.fields.get('job-id', 0)
+        username = str(self.fields.get('username', prop.username))
+        try:
+            job_id = int(self.fields.get('job-id', 0))
+        except ValueError:
+            job_id = 0
 
         if self.payload and (username, job_id) in fax_file and \
             not fax_file_ready[(username, job_id)]:
@@ -373,12 +379,18 @@
 
     # sent by hpfax: to indicate the end of a complete fax rendering job
     def handle_hpfaxend(self):
-        username = self.fields.get('username', '')
-        job_id = self.fields.get('job-id', 0)
-        printer_name = self.fields.get('printer', '')
-        device_uri = self.fields.get('device-uri', '').replace('hp:', 'hpfax:')
-        title = self.fields.get('title', '')
-        job_size = self.fields.get('job-size', 0)
+        username = str(self.fields.get('username', ''))
+        try:
+            job_id = int(self.fields.get('job-id', 0))
+        except ValueError:
+            job_id = 0
+        printer_name = str(self.fields.get('printer', ''))
+        device_uri = str(self.fields.get('device-uri', '')).replace('hp:', 'hpfax:')
+        title = str(self.fields.get('title', ''))
+        try:
+            job_size = int(self.fields.get('job-size', 0))
+        except ValueError:
+            job_size = 0
 
         fax_file[(username, job_id)].seek(0)
         fax_file_ready[(username, job_id)] = True
@@ -389,7 +401,7 @@
 
     # sent by hp-sendfax to see if any faxes have been printed and need to be picked up
     def handle_faxcheck(self):
-        username = self.fields.get('username', '')
+        username = str(self.fields.get('username', ''))
         result_code = ERROR_NO_DATA_AVAILABLE
         other_fields = {}
 
@@ -413,8 +425,11 @@
     # after being run with --job param, both after a hpfaxend message
     def handle_faxgetdata(self):
         result_code = ERROR_SUCCESS
-        username = self.fields.get('username', '')
-        job_id = self.fields.get('job-id', 0)
+        username = str(self.fields.get('username', ''))
+        try:
+            job_id = int(self.fields.get('job-id', 0))
+        except ValueError:
+            job_id = 0
 
         try:
             fax_file[(username, job_id)]
@@ -442,15 +457,18 @@
     # EVENT
     def handle_event(self):
         gui_port, gui_host = None, None
-        event_type = self.fields.get('event-type', 'event')
+        event_type = str(self.fields.get('event-type', 'event'))
         
-        event_code = self.fields.get('event-code', STATUS_PRINTER_IDLE)
+        try:
+            event_code = int(self.fields.get('event-code', STATUS_PRINTER_IDLE))
+        except ValueError:
+            event_code = STATUS_PRINTER_IDLE
         
         # If event-code > 10001, its a PJL error code, so convert it
         if event_code > EVENT_MAX_EVENT:
             event_code = status.MapPJLErrorCode(event_code)
             
-        device_uri = self.fields.get('device-uri', '').replace('hpfax:', 'hp:')
+        device_uri = str(self.fields.get('device-uri', '')).replace('hpfax:', 'hp:')
         result_code = self.__checkdevice(device_uri)
         if result_code != ERROR_SUCCESS:
             return
@@ -461,7 +479,10 @@
 
         log.debug("Short/Long: %s/%s" % (error_string_short, error_string_long))
 
-        job_id = self.fields.get('job-id', 0)
+        try:
+            job_id = int(self.fields.get('job-id', 0))
+        except ValueError:
+            job_id = 0
 
         try:
             username = self.fields['username']
@@ -480,7 +501,10 @@
 
         no_fwd = utils.to_bool(self.fields.get('no-fwd', '0'))
         log.debug("Username (jobid): %s (%d)" % (username, job_id))
-        retry_timeout = self.fields.get('retry-timeout', 0)
+        try:
+            retry_timeout = int(self.fields.get('retry-timeout', 0))
+        except ValueError:
+            retry_timeout = 0
         user_alerts = alerts.get(username, {})        
 
         dup_event = False
