From 90da22252d32a3740b3d785cad8a4b2dac35a379 Mon Sep 17 00:00:00 2001 From: Louis Lagendijk Date: Jan 22 2014 13:31:13 +0000 Subject: Temporary fix for issues with new printers that send an xml-document for printer status --- 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@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 - 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 - 1.2.1-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild