summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Untz <vuntz@novell.com>2010-02-16 21:44:56 +0100
committerVincent Untz <vuntz@novell.com>2010-02-16 21:44:56 +0100
commit52c5e69dfbecf98da57215ecbf48e8d61c65f660 (patch)
treea1d1b8cd0da11c654bdd599ecf8e567fd68bd50c
parent2e06c3ba13e6dc5df66e19de8a80f30e27136936 (diff)
Add check for string length in validity checks
Apparently, CUPS can do bad things when strings are too long, like creating a new line and evaluating it as an instruction. So we just make sure that strings are not too long. We use a maximum length of 512 right now, which should be enough for all uses. https://bugzilla.novell.com/show_bug.cgi?id=447444
-rw-r--r--src/cups.c68
1 files changed, 47 insertions, 21 deletions
diff --git a/src/cups.c b/src/cups.c
index f11a949..8c3475d 100644
--- a/src/cups.c
+++ b/src/cups.c
@@ -231,18 +231,30 @@ cph_cups_new (void)
* Validation
******************************************************/
+/* From https://bugzilla.novell.com/show_bug.cgi?id=447444#c5
+ * We need to define a maximum length for strings to avoid cups
+ * thinking there are multiple lines.
+ */
+#define CPH_STR_MAXLEN 512
+
static gboolean
_cph_cups_is_string_printable (const char *str,
- gboolean check_for_null)
+ gboolean check_for_null,
+ int maxlen)
{
int i;
+ int len;
/* no NULL string */
if (!str)
return !check_for_null;
+ len = strlen (str);
+ if (maxlen > 0 && len > maxlen)
+ return FALSE;
+
/* only printable characters */
- for (i = 0; i < strlen (str); i++) {
+ for (i = 0; i < len; i++) {
if (!g_ascii_isprint (str[i]))
return FALSE;
}
@@ -250,14 +262,14 @@ _cph_cups_is_string_printable (const char *str,
return TRUE;
}
-#define _CPH_CUPS_IS_VALID(name, name_for_str, check_for_null) \
+#define _CPH_CUPS_IS_VALID(name, name_for_str, check_for_null, maxlen) \
static gboolean \
_cph_cups_is_##name##_valid (CphCups *cups, \
const char *str) \
{ \
char *error; \
\
- if (_cph_cups_is_string_printable (str, check_for_null)) \
+ if (_cph_cups_is_string_printable (str, check_for_null, maxlen)) \
return TRUE; \
\
error = g_strdup_printf ("\"%s\" is not a valid %s.", \
@@ -272,13 +284,20 @@ static gboolean
_cph_cups_is_printer_name_valid_internal (const char *name)
{
int i;
+ int len;
/* no empty string */
if (!name || name[0] == '\0')
return FALSE;
+ len = strlen (name);
+ /* no string that is too long; see comment at the beginning of the
+ * validation code block */
+ if (len > CPH_STR_MAXLEN)
+ return FALSE;
+
/* only printable characters, no space, no /, no # */
- for (i = 0; i < strlen (name); i++) {
+ for (i = 0; i < len; i++) {
if (!g_ascii_isprint (name[i]))
return FALSE;
if (g_ascii_isspace (name[i]))
@@ -294,11 +313,18 @@ static gboolean
_cph_cups_is_scheme_valid_internal (const char *scheme)
{
int i;
+ int len;
/* no empty string */
if (!scheme || scheme[0] == '\0')
return FALSE;
+ len = strlen (scheme);
+ /* no string that is too long; see comment at the beginning of the
+ * validation code block */
+ if (len > CPH_STR_MAXLEN)
+ return FALSE;
+
/* From RFC 1738:
* Scheme names consist of a sequence of characters. The lower case
* letters "a"--"z", digits, and the characters plus ("+"), period
@@ -306,7 +332,7 @@ _cph_cups_is_scheme_valid_internal (const char *scheme)
* interpreting URLs should treat upper case letters as equivalent to
* lower case in scheme names (e.g., allow "HTTP" as well as "http").
*/
- for (i = 0; i < strlen (scheme); i++) {
+ for (i = 0; i < len; i++) {
if (!g_ascii_isalnum (scheme[i]) &&
scheme[i] != '+' &&
scheme[i] != '.' &&
@@ -397,12 +423,12 @@ _cph_cups_is_scheme_valid (CphCups *cups,
* printer-error-policy-supported and printer-op-policy-supported
* attributes.
*/
-_CPH_CUPS_IS_VALID (printer_uri, "printer URI", TRUE)
-_CPH_CUPS_IS_VALID (ppd, "PPD", TRUE)
-_CPH_CUPS_IS_VALID (ppd_filename, "PPD file", FALSE)
-_CPH_CUPS_IS_VALID (job_sheet, "job sheet", FALSE)
-_CPH_CUPS_IS_VALID (error_policy, "error policy", FALSE)
-_CPH_CUPS_IS_VALID (op_policy, "op policy", FALSE)
+_CPH_CUPS_IS_VALID (printer_uri, "printer URI", TRUE, CPH_STR_MAXLEN)
+_CPH_CUPS_IS_VALID (ppd, "PPD", TRUE, CPH_STR_MAXLEN)
+_CPH_CUPS_IS_VALID (ppd_filename, "PPD file", FALSE, CPH_STR_MAXLEN)
+_CPH_CUPS_IS_VALID (job_sheet, "job sheet", FALSE, CPH_STR_MAXLEN)
+_CPH_CUPS_IS_VALID (error_policy, "error policy", FALSE, CPH_STR_MAXLEN)
+_CPH_CUPS_IS_VALID (op_policy, "op policy", FALSE, CPH_STR_MAXLEN)
/* Check for users. Those are some printable strings, which souldn't be NULL.
* They should also not be empty, but it appears that it's possible to carry
@@ -411,7 +437,7 @@ _CPH_CUPS_IS_VALID (op_policy, "op policy", FALSE)
* We could also check that the username exists on the system, but cups will do
* it.
*/
-_CPH_CUPS_IS_VALID (user, "user", TRUE)
+_CPH_CUPS_IS_VALID (user, "user", TRUE, CPH_STR_MAXLEN)
/* Check for options & values. Those are for sure some printable strings, but
* can we do more? Let's see:
@@ -420,14 +446,14 @@ _CPH_CUPS_IS_VALID (user, "user", TRUE)
* and so we'll let cups handle that.
* + a value can be some text, and we don't know much more.
*/
-_CPH_CUPS_IS_VALID (option, "option", TRUE)
-_CPH_CUPS_IS_VALID (option_value, "value for option", FALSE)
+_CPH_CUPS_IS_VALID (option, "option", TRUE, CPH_STR_MAXLEN)
+_CPH_CUPS_IS_VALID (option_value, "value for option", FALSE, CPH_STR_MAXLEN)
/* This is really just some text */
-_CPH_CUPS_IS_VALID (info, "description", FALSE)
-_CPH_CUPS_IS_VALID (location, "location", FALSE)
-_CPH_CUPS_IS_VALID (reject_jobs_reason, "reason", FALSE)
-_CPH_CUPS_IS_VALID (job_hold_until, "job hold until", FALSE)
+_CPH_CUPS_IS_VALID (info, "description", FALSE, CPH_STR_MAXLEN)
+_CPH_CUPS_IS_VALID (location, "location", FALSE, CPH_STR_MAXLEN)
+_CPH_CUPS_IS_VALID (reject_jobs_reason, "reason", FALSE, CPH_STR_MAXLEN)
+_CPH_CUPS_IS_VALID (job_hold_until, "job hold until", FALSE, CPH_STR_MAXLEN)
/* For put/get file: this is some text, but we could potentially do more
* checks. We don't do them because cups will already do them.
@@ -435,8 +461,8 @@ _CPH_CUPS_IS_VALID (job_hold_until, "job hold until", FALSE)
* + for the filename, in the put case, we could check that the file exists
* and is a regular file (no socket, block device, etc.).
*/
-_CPH_CUPS_IS_VALID (resource, "resource", TRUE)
-_CPH_CUPS_IS_VALID (filename, "filename", TRUE)
+_CPH_CUPS_IS_VALID (resource, "resource", TRUE, CPH_STR_MAXLEN)
+_CPH_CUPS_IS_VALID (filename, "filename", TRUE, CPH_STR_MAXLEN)
/******************************************************
* Helpers