[Fedora-directory-commits] adminutil/lib/libadminutil form_post.c, 1.10, 1.11

Richard Allen Megginson rmeggins at fedoraproject.org
Wed Dec 3 17:31:28 UTC 2008


Author: rmeggins

Update of /cvs/dirsec/adminutil/lib/libadminutil
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv3272/adminutil/lib/libadminutil

Modified Files:
	form_post.c 
Log Message:
Resolves: bug 462411
Bug Description: certificate request wizard returns an error
Reviewed by: nkinder (Thanks!)
Fix Description: This was broken as part of the fix for the XSS issues. To fix that, in order to make sure we never displayed any string that contained unescaped HTML entities, we just go ahead and escape everything when we read the values from the CGI GET or POST arguments.   For this particular bug, this meant the cert CGI was getting a DN like this: CN="ldap.example.com" instead of CN="ldap.example.com".  The solution is to add some functions to adminutil (stolen from dsgw) that can be used to escape/unescape HTML entities.  We have to be careful never to display unescaped strings - in this particular case, the DN is never printed.
Platforms tested: RHEL5
Flag Day: yes - will require new adminutil, adminserver
Doc impact: no



Index: form_post.c
===================================================================
RCS file: /cvs/dirsec/adminutil/lib/libadminutil/form_post.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- form_post.c	27 Aug 2008 20:02:23 -0000	1.10
+++ form_post.c	3 Dec 2008 17:31:26 -0000	1.11
@@ -82,6 +82,100 @@
     return input;
 }
 
+#define ADMINUTIL_MAX_ENTITY_LEN			6	/* " */
+static char	*specials = "&\"<>\'";
+static char	*entities[] = { "&", """, "<", ">", "'" };
+static int entitylen[] = { 5, 6, 4, 4, 5 };
+static int entitynum = sizeof(entities)/sizeof(entities[0]);
+
+PR_IMPLEMENT(char *)
+strdup_escape_entities( char *s, int *madecopyp )
+{
+/*
+ * If the UTF8 string "s" contains any HTML special characters, make a
+ * duplicate where the appropriate HTML "entities" have been substituted
+ * for the special chars.  For example, "<mcs at ace.com>" will be translated
+ * to "<mcs at ace.com>".
+ * 
+ * If "s" does not contain any special characters, it is returned and
+ *	*madecopyp is set to 0.
+ * Otherwise a malloc'd string is returned and *madecopyp is set to 1.
+ */
+    int		spcount, idx;
+    char	*p, *q, *r, *d;
+
+    spcount = 0;
+    for ( p = s; *p != '\0'; LDAP_UTF8INC( p )) {
+        if ( ((*p) & 0x80) == 0 && strchr( specials, *p ) != NULL ) {
+            ++spcount;
+        }
+    }
+
+    if ( spcount == 0 ) {
+        *madecopyp = 0;
+        return( s );
+    }
+
+    d = r = PR_Malloc( strlen( s ) + 1 + spcount * ADMINUTIL_MAX_ENTITY_LEN );
+    for ( p = s; *p != '\0'; LDAP_UTF8INC( p )) {
+        if ( ((*p) & 0x80) == 0 && ( q = strchr( specials, *p )) != NULL ) {
+            idx = ( q - specials );
+            memcpy( r, entities[ idx ], entitylen[ idx ] );
+            r += entitylen[ idx ];
+        } else {
+            r += LDAP_UTF8COPY( r, p );
+        }
+    }
+    *r = '\0';
+
+    *madecopyp = 1;
+    return( d );
+}
+
+/* this will convert a string with escaped entities ("&")
+   back to the original unescaped string ("&")
+   This is necessary for converting URLs which would normally
+   have entities in them (e.g. search?context=foo&dn=bar)
+   for use in javascript (e.g. window.href = 'search?context=foo&dn=bar')
+   since javascript must use the unescaped version
+   This converts the string in place since the entities "&"
+   take up much more room than the single character represented
+   If you need to work on a copy then make a copy with strdup first.
+*/
+PR_IMPLEMENT(void)
+unescape_entities(char *s)
+{
+    int		idx;
+    char	*p, *r, *d;
+
+    if (!s || !*s) {
+        return;
+    }
+
+    d = r = s;
+    for ( p = s; *p != '\0'; LDAP_UTF8INC( p )) {
+        if ( ((*p) & 0x80) == 0 && ( (*p) == '&') ) {
+            for( idx = 0; idx < entitynum; ++idx ) {
+                if (!strncmp(p, entities[ idx ], entitylen[ idx ])) {
+                    break;
+                }
+            }
+            if (idx < entitynum) {
+                *r = specials[idx];
+                ++r;
+                p += entitylen[ idx ]-1; /* the 1 will be added in the for loop */
+            } else {
+                r += LDAP_UTF8COPY( r, p );
+            }
+        } else {
+            r += LDAP_UTF8COPY( r, p );
+        }
+    }
+    *r = '\0';
+
+    return;
+}
+
 PR_IMPLEMENT(void)
 form_unescape(char *str) 
 {




More information about the Fedora-directory-commits mailing list