[cups-bjnp] Temporary fix for issues with new printers that send an xml-document for printer status

Louis Lagendijk llagendijk at fedoraproject.org
Wed Jan 22 13:32:11 UTC 2014


commit 90da22252d32a3740b3d785cad8a4b2dac35a379
Author: Louis Lagendijk <louis.lagendijk at gmail.com>
Date:   Wed Jan 22 14:31:13 2014 +0100

    Temporary fix for issues with new printers that send an xml-document for printer status

 cups-bjnp-2014-01-22.patch |  361 ++++++++++++++++++++++++++++++++++++++++++++
 cups-bjnp.spec             |    6 +
 2 files changed, 367 insertions(+), 0 deletions(-)
---
diff --git a/cups-bjnp-2014-01-22.patch b/cups-bjnp-2014-01-22.patch
new file mode 100644
index 0000000..440ddbe
--- /dev/null
+++ b/cups-bjnp-2014-01-22.patch
@@ -0,0 +1,361 @@
+Index: bjnp.h
+===================================================================
+--- bjnp.h	(revision 67)
++++ bjnp.h	(working copy)
+@@ -42,9 +42,9 @@
+ #define BJNP_PORT_MAX 64        /* max length of port string */
+ #define BJNP_ARGS_MAX 128       /* max size of argument string */
+ #define BJNP_MODEL_MAX 64	/* max allowed size for make&model */
+-#define BJNP_IEEE1284_MAX 1024	/* max. allowed size of IEEE1284 id */
+ #define BJNP_SERIAL_MAX 16	/* siuze of serial (mac-address) string */
+ #define BJNP_SOCK_MAX 256	/* maximum number of open sockets */
++#define BJNP_UDP_MAX 65536	/* maximum size of a UDP packet */
+ #define BJNP_PRINTERS_MAX 64	/* nax. number of printers in discovery */
+ #define KEEP_ALIVE_SECONDS 3	/* max interval/2 seconds before we */
+ 				/* send an empty data packet to the */
+@@ -52,6 +52,14 @@
+ #define BJNP_MAX_BROADCAST_ATTEMPTS 2   /* number of broadcast packets to be sent */
+ #define BJNP_BROADCAST_INTERVAL 10      /* ms between broadcasts */
+ 
++/* IEEE1284 related definitons */
++#define BST_PRINTING 0x80
++#define BST_BUSY     0x20
++#define BST_OPCALL   0x08
++#define STR_BST      "BST:"
++#define STR_DES	     "DES:"
++
++
+ #define USLEEP_MS 1000                  /* sleep for 1 msec */
+ #define BJNP_BC_RESPONSE_TIMEOUT 500    /* waiting time for broadc. responses */
+ #define BJNP_PORT_PRINT 8611
+Index: bjnp-io.c
+===================================================================
+--- bjnp-io.c	(revision 67)
++++ bjnp-io.c	(working copy)
+@@ -263,9 +263,10 @@
+ 
+   payload_len = ntohl(response.tcp_print_response.header.payload_len);
+ 
+-  /* it should be the same size as the accepted field */
++  /* it should be at least the same size as the accepted field */
+ 
+-  if (payload_len >= sizeof(response.tcp_print_response.accepted))
++  if ( (payload_len >= sizeof(response.tcp_print_response.accepted)) &&
++       (payload_len < (sizeof(response) - sizeof(struct bjnp_header) ) ) )
+     {
+       /* read nr of bytes accepted by printer */
+ 
+@@ -300,6 +301,8 @@
+     {
+       /* there is no payload, assume 0 bytes received */
+       *written = 0;
++      errno = EIO;
++      return BJNP_IO_ERROR;
+     }
+ 
+ 
+Index: README
+===================================================================
+--- README	(revision 67)
++++ README	(working copy)
+@@ -74,16 +74,4 @@
+ are sent back to the computer TO port 8611. Connection tracking however does not
+ see a match. You will therefore have to allow packets received TO port 8611 as well.
+ 
+-Louis Lagendijk
+ louis.lagendijk at gmail.com
+-
+-ChangeLog
+-2012-08-31 Added IPv6 support
+-           Refactored into a number of c-files
+-2011-07-05 Version 1.0
+-           Fixed some warnings from the latest GCC on unused code
+-           Made hostname resolution for the printer more robust by verifying
+-           that a forward lookup matches the reverse name lookup.
+-           This should fix printer detection for some buggy routers that 
+-           return a bogus hostname on a reverse lookup
+-           Bumped version number to 1.0 the code seems to be stable.
+Index: bjnp-debug.c
+===================================================================
+--- bjnp-debug.c	(revision 67)
++++ bjnp-debug.c	(working copy)
+@@ -265,8 +265,11 @@
+ 
+ 
+   if ((debug_file = fopen (CUPS_LOGDIR "/" LOGFILE, "w")) == NULL)
+-    bjnp_debug(LOG_WARN, "Can not open logfile: %s - %s\n", 
++    {
++      bjnp_debug(LOG_WARN, "Can not open logfile: %s - %s, sending output to stdout instead\n", 
+                CUPS_LOGDIR "/" LOGFILE, strerror(errno));
++      debug_file=stdout;
++    }
+   
+   bjnp_debug (LOG_INFO, "BJNP debug level = %s\n", level2str (debug_level));
+ }
+Index: INSTALL
+===================================================================
+--- INSTALL	(revision 67)
++++ INSTALL	(working copy)
+@@ -1,7 +1,7 @@
+ Installation Instructions
+ *************************
+ 
+-Copyright (C) 1994-1996, 1999-2002, 2004-2012 Free Software Foundation,
++Copyright (C) 1994-1996, 1999-2002, 2004-2013 Free Software Foundation,
+ Inc.
+ 
+    Copying and distribution of this file, with or without modification,
+Index: bjnp-runloop.c
+===================================================================
+--- bjnp-runloop.c	(revision 67)
++++ bjnp-runloop.c	(working copy)
+@@ -373,7 +373,7 @@
+ 	       * Read error - bail if we don't see EAGAIN or EINTR...
+ 	       */
+ 
+-	      if (errno != EAGAIN || errno != EINTR)
++	      if (errno != EAGAIN && errno != EINTR)
+ 		{
+ 		  perror ("ERROR: Unable to read print data");
+ 		  return (-1);
+Index: bjnp-utils.c
+===================================================================
+--- bjnp-utils.c	(revision 67)
++++ bjnp-utils.c	(working copy)
+@@ -126,9 +126,15 @@
+ 
+   char s[BJNP_IEEE1284_MAX];
+   char *tok;
++  int len;
+ 
++  model[0] = '\0';
++  len  = strlen(printer_id);
++  if ( (len  > BJNP_IEEE1284_MAX) || (len < 0))
++    {
++      bjnp_debug(LOG_ERROR, "printer id string (length) incorrect: %d\n", len);
++    }
+   strcpy (s, printer_id);
+-  model[0] = '\0';
+ 
+   tok = strtok (s, ";");
+   while (tok != NULL)
+@@ -135,9 +141,9 @@
+     {
+       /* DES contains make and model */
+ 
+-      if (strncmp (tok, "DES:", 4) == 0)
++      if (strncmp (tok, STR_DES, strlen(STR_DES)) == 0)
+ 	{
+-	  strcpy (model, tok + 4);
++	  strcpy (model, tok + strlen(STR_DES));
+ 	  return 1;
+ 	}
+       tok = strtok (NULL, ";");
+@@ -146,6 +152,61 @@
+ }
+ 
+ int
++parse_status_to_paperout (int len, char *status_str)
++{
++/*
++ * parses the  status string of the printer to retrieve paper status
++ * of the printer
++ * Returns: BJNP_PAPER_OK = paper ok
++ *          BJNP_PAPER_OUT = out of paper
++ *          BJNP_PAPER_UNKNOWN = paper status not found
++ */
++
++  char *tok;
++  unsigned int status;
++
++  /*
++   * the status string may contain only the IEEE1284 status or an xml-document
++   * that contains the IEEE1284 status as one of
++   * we simply ignonre this, and look only for the BST status
++   */
++
++  if( len < 0 || len > BJNP_UDP_MAX ) {
++        bjnp_debug( LOG_ERROR, "Received a status report with incorrect length: %d\n", len);
++        return BJNP_PAPER_UNKNOWN;
++  }
++
++  status_str[len] = '\0';
++
++  /* BST contains the status */
++  if ( (tok = strstr(status_str, STR_BST)) != NULL)
++    {
++      if (sscanf (tok + strlen(STR_BST), "%2x", &status) == 1)
++        {
++          bjnp_debug (LOG_DEBUG,
++                      "Read printer status: %u\n  Printing = %d\n  Busy = %d\n  PaperOut = %d\n",
++                      status, ((status & BST_PRINTING) != 0),
++                      ((status & BST_BUSY) != 0),
++                      ((status & BST_OPCALL) != 0));
++          if (status & BST_OPCALL)
++            {
++              bjnp_debug (LOG_INFO, "Paper out!\n");
++              return  BJNP_PAPER_OUT;
++            }
++          else
++            {
++              bjnp_debug (LOG_INFO, "Paper ok!\n");
++              return BJNP_PAPER_OK;
++            }
++        }
++    }
++  bjnp_debug (LOG_WARN, "Could not parse printer status for tag: %s!\n",
++              STR_BST);
++  return  BJNP_PAPER_UNKNOWN;
++}
++
++
++int
+ charTo2byte (char d[], char s[], int len)
+ {
+   /*
+Index: bjnp-commands.c
+===================================================================
+--- bjnp-commands.c	(revision 67)
++++ bjnp-commands.c	(working copy)
+@@ -23,61 +23,6 @@
+ static int serial = 0;
+ uint16_t  session_id = 0;
+ 
+-int
+-parse_status_to_paperout (int len, char *status_str)
+-{
+-/*
+- * parses the  status string of the printer to retrieve paper status
+- * of the printer
+- * Returns: BJNP_PAPER_OK = paper ok
+- *          BJNP_PAPER_OUT = out of paper
+- *          BJNP_PAPER_UNKNOWN = paper status not found
+- */
+-
+-  char s[BJNP_IEEE1284_MAX];
+-  char *tok;
+-  unsigned int status;
+-
+-  strcpy (s, status_str);
+-  s[len] = '\0';
+-
+-  tok = strtok (s, ";");
+-  while (tok != NULL)
+-    {
+-      /* BST contains status */
+-
+-      if (strncmp (tok, STR_BST, strlen (STR_BST)) == 0)
+-        {
+-          if (sscanf (tok + 4, "%2x", &status) != 1)
+-            {
+-              bjnp_debug (LOG_WARN, "Could not parse paper status tag: %s!\n",
+-                          STR_BST);
+-              return BJNP_PAPER_UNKNOWN;
+-            }
+-          else
+-            {
+-              bjnp_debug (LOG_DEBUG,
+-                          "Read printer status: %u\n  Printing = %d\n  Busy = %d\n  PaperOut = %d\n",
+-                          status, ((status & BST_PRINTING) != 0),
+-                          ((status & BST_BUSY) != 0),
+-                          ((status & BST_OPCALL) != 0));
+-              if (status & BST_OPCALL)
+-                {
+-                  bjnp_debug (LOG_INFO, "Paper out!\n");
+-                  return BJNP_PAPER_OUT;
+-                }
+-              else
+-                {
+-                  bjnp_debug (LOG_INFO, "Paper ok!\n");
+-                  return BJNP_PAPER_OK;
+-                }
+-            }
+-        }
+-      tok = strtok (NULL, ";");
+-    }
+-  return BJNP_PAPER_UNKNOWN;
+-}
+-
+ void
+ clear_cmd(bjnp_command_t * cmd)
+ {
+@@ -104,8 +49,6 @@
+   return serial;
+ }
+ 
+-
+-
+ static int
+ bjnp_process_udp_command (http_addr_t * addr, bjnp_command_t *command, int cmd_len, bjnp_response_t *response)
+ {
+@@ -215,9 +158,11 @@
+ 
+   id_len = ntohs (id.udp_identity_response.id_len) - sizeof (id.udp_identity_response.id_len);
+ 
++  /* check id_len */
++
+   if ( (id_len < 0) || (id_len > (resp_len - bjnp_header_size) ) || ( id_len > BJNP_IEEE1284_MAX) )
+     {
+-      bjnp_debug( LOG_DEBUG, "Id - length recieved is invalid: %d (total response length = %d\n",
++      bjnp_debug( LOG_ERROR, "Id - length recieved is invalid: %d (total response length = %d\n",
+                   id_len, resp_len);
+       return -1;
+     } 
+@@ -236,6 +181,7 @@
+ 
+   if (model != NULL)
+     {
++      model[0] = '\0';
+       parse_IEEE1284_to_model (printer_id, model);
+       bjnp_debug (LOG_DEBUG, "Printer model = %s\n", model);
+     }
+Index: bjnp.c
+===================================================================
+--- bjnp.c	(revision 67)
++++ bjnp.c	(working copy)
+@@ -61,7 +61,7 @@
+   char method[255],		/* Method in URI */
+     hostname[1024],		/* Hostname */
+     username[255],		/* Username info (not used) */
+-    resource[1024],		/* Resource info (not used) */
++    resource[1024],		/* Resource info */
+    *options,			/* Pointer to options */
+    *name,			/* Name of option */
+    *value,			/* Value of option */
+@@ -134,7 +134,8 @@
+ 		    printers[i].port,
+ 		    printers[i].model,
+ 		    printers[i].model,
+-		    printers[i].hostname, printers[i].IEEE1284_id);
++       		    printers[i].hostname, 
++                    printers[i].IEEE1284_id);
+ 	  }
+ 
+       return (CUPS_BACKEND_OK);
+Index: bjnp-protocol.h
+===================================================================
+--- bjnp-protocol.h	(revision 67)
++++ bjnp-protocol.h	(working copy)
+@@ -144,7 +144,7 @@
+     {
+       struct bjnp_header header;
+       uint16_t status_len;	/* length of status field */
+-      char status[2048];	
++      char status[BJNP_UDP_MAX];
+     } udp_status_response;
+   
+   struct  __attribute__ ((__packed__))
+@@ -153,12 +153,7 @@
+       uint16_t id_len;		/* length of identity field */
+       char id[2048];		/* identity */
+     } udp_identity_response;
+-  char fillers[4096]; 
++  char fillers[65536]; 
+ } bjnp_response_u;
+ 
+-#define BST_PRINTING 0x80
+-#define BST_BUSY     0x20
+-#define BST_OPCALL   0x08
+-#define STR_BST      "BST:"
+-
+ #endif /* _CUPS_BJNP_PROTOCOL_H_ */
diff --git a/cups-bjnp.spec b/cups-bjnp.spec
index 1693149..95512cb 100644
--- a/cups-bjnp.spec
+++ b/cups-bjnp.spec
@@ -7,6 +7,7 @@ Source		: http://downloads.sourceforge.net/cups-bjnp/cups-bjnp-%{version}.tar.gz
 Group		: System Environment/Daemons
 URL		: https://sourceforge.net/projects/cups-bjnp/
 BuildRoot	: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
+Patch1          : cups-bjnp-2014-01-22.patch
 
 BuildRequires:	cups-devel
 Requires: cups
@@ -18,6 +19,7 @@ proprietary BJNP network protocol.
 
 %prep
 %setup -q
+%patch1 -p0 -b .latest
 
 %build
 %configure --prefix=%{_exec_prefix} --with-cupsbackenddir=%{cups_backend_dir} --disable-Werror
@@ -36,6 +38,10 @@ rm -Rf $RPM_BUILD_ROOT
 %doc COPYING ChangeLog TODO NEWS README
 
 %changelog
+* Wed Jan 22 2014  Louis Lagendijk <llagendijk at users.sourceforge.net> - 1.2.1-3
+- Fix crash with newer printers that send an xml-document for printer status
+- Fix possible buffer overflow on response buffer
+
 * Sat Aug 03 2013 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 1.2.1-2
 - Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild
 


More information about the scm-commits mailing list