summaryrefslogtreecommitdiffstats
path: root/ldap/clients/dsgw/cgiutil.c
diff options
context:
space:
mode:
Diffstat (limited to 'ldap/clients/dsgw/cgiutil.c')
-rw-r--r--ldap/clients/dsgw/cgiutil.c547
1 files changed, 0 insertions, 547 deletions
diff --git a/ldap/clients/dsgw/cgiutil.c b/ldap/clients/dsgw/cgiutil.c
deleted file mode 100644
index 99413142..00000000
--- a/ldap/clients/dsgw/cgiutil.c
+++ /dev/null
@@ -1,547 +0,0 @@
-/** --- BEGIN COPYRIGHT BLOCK ---
- * This Program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free Software
- * Foundation; version 2 of the License.
- *
- * This Program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * In addition, as a special exception, Red Hat, Inc. gives You the additional
- * right to link the code of this Program with code not covered under the GNU
- * General Public License ("Non-GPL Code") and to distribute linked combinations
- * including the two, subject to the limitations in this paragraph. Non-GPL Code
- * permitted under this exception must only link to the code of this Program
- * through those well defined interfaces identified in the file named EXCEPTION
- * found in the source code files (the "Approved Interfaces"). The files of
- * Non-GPL Code may instantiate templates or use macros or inline functions from
- * the Approved Interfaces without causing the resulting work to be covered by
- * the GNU General Public License. Only Red Hat, Inc. may make changes or
- * additions to the list of Approved Interfaces. You must obey the GNU General
- * Public License in all respects for all of the Program code and other code used
- * in conjunction with the Program except the Non-GPL Code covered by this
- * exception. If you modify this file, you may extend this exception to your
- * version of the file, but you are not obligated to do so. If you do not wish to
- * provide this exception without modification, you must delete this exception
- * statement from your version and license this file solely under the GPL without
- * exception.
- *
- *
- * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
- * Copyright (C) 2005 Red Hat, Inc.
- * All rights reserved.
- --- END COPYRIGHT BLOCK --- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-/*
- * cgiutil.c -- CGI-related utility functions -- HTTP gateway
- *
- * Note: tihs code is derived from the extras/changepw.c code that ships
- * with the FastTrack 2.0 server
- */
-
-#include "dsgw.h"
-#include "dbtdsgw.h"
-
-#include <prprf.h>
-#include <unicode/ucnv.h>
-#include <unicode/ustring.h>
-
-/* globals */
-static char **formvars = NULL;
-
-/* functions */
-static char **dsgw_string_to_vec(char *in);
-
-static void
-dsgw_vec_convert (char** vec)
- /* Convert input from the charset named in it (if any) to UTF_8.
- Either return s, or free(s) and return the converted string.
- */
-{
- static const char* prefix = "charset=";
- const size_t prefix_len = strlen (prefix);
- char** v;
-
- if (vec) for (v = vec; *v; ++v) {
- if (!strncmp (*v, prefix, prefix_len)) {
- char* charset = *v + prefix_len;
- UConverter* converter = NULL;
- UErrorCode err = U_ZERO_ERROR;
- if ( ! is_UTF_8 (charset) && (converter = ucnv_open(charset, &err)) &&
- (err == U_ZERO_ERROR) ) {
- for (v = vec; *v; ++v) {
- char* s = strchr (*v, '=');
- if (s != NULL) {
- char *t = NULL;
- const size_t nlen = (++s) - *v;
- const size_t slen = strlen (s);
- size_t tlen = 0;
- size_t reallen = 0;
- int result;
-
- if (ucnv_getMaxCharSize(converter) == 1) {
- tlen = slen + 2; /* best case - ascii or other 7/8 bit */
- } else { /* assume worst case utf8 - each char is 3 bytes */
- tlen = (slen * 3) + 2;
- }
- do {
- char *tptr;
- size_t realSlen = 0;
- err = U_ZERO_ERROR;
-
- if (t) {
- t = dsgw_ch_realloc(t, nlen + tlen);
- } else {
- t = dsgw_ch_malloc(nlen + tlen);
- }
- tptr = t + nlen;
-
- /* copy the converted characters into t after the '=', and
- leave room for the trailing 0 */
- result = dsgw_convert(DSGW_TO_UTF8, converter,
- &tptr, (tlen - nlen - 1), &reallen,
- s, slen, &realSlen, &err);
- tlen += slen; /* if failed, make more room */
- } while (result == 0);
- if ((result == 1) && (err == U_ZERO_ERROR)) {
- memcpy (t, *v, nlen);
- t[nlen+reallen] = '\0';
- free (*v);
- *v = t;
- } else {
- free (t);
- }
- ucnv_reset (converter); /* back to initial shift state */
- }
- }
- ucnv_close (converter);
- }
- if (U_FAILURE(err)) {
- dsgw_error(DSGW_ERR_CHARSET_NOT_SUPPORTED, charset, 0, 0, 0);
- }
- break;
- }
- }
-}
-
-/* Read in the variables from stdin, unescape them, and then put them in
- * the static vector.
- *
- * Return 0 if all goes well; DSGW error code otherwise
- */
-int
-dsgw_post_begin(FILE *in)
-{
- char *ct, *vars = NULL, *tmp = NULL;
- int cl;
-
- if (( ct = getenv( "CONTENT_TYPE" )) == NULL ||
- strcasecmp( ct, "application/x-www-form-urlencoded" ) != 0 ||
- ( tmp = getenv( "CONTENT_LENGTH" )) == NULL ) {
- return( DSGW_ERR_BADFORMDATA );
- }
-
- cl = atoi(tmp);
-
- vars = (char *)dsgw_ch_malloc(cl+1);
-
- if ( fread(vars, 1, cl, in) != cl ) {
- return( DSGW_ERR_BADFORMDATA );
- }
-
- vars[cl] = '\0';
-#ifdef DSGW_DEBUG
- dsgw_log ("vars=\"%s\"\n", vars);
-#endif
- formvars = dsgw_string_to_vec (vars);
- free( vars );
- dsgw_vec_convert (formvars);
-
-#ifdef DSGW_DEBUG
- dsgw_logstringarray( "formvars", formvars );
-if (0) {
- char** var = formvars;
- if (var) {
- printf ("Content-type: text/html;charset=UTF-8\n\n<HTML><BODY>\n");
- for (; *var; ++var) {
- printf ("%s<br>\n", *var);
- }
- printf ("</BODY></HTML>\n");
- exit (1);
- }
-}
-#endif
-
- return( 0 );
-}
-
-
-/* Unescape the %xx variables as they're sent in. */
-void
-dsgw_form_unescape(char *str)
-{
- register int x = 0, y = 0;
- int l = strlen(str);
- char digit;
-
- while(x < l) {
- if((str[x] == '%') && (x < (l - 2))) {
- ++x;
- digit = (str[x] >= 'A' ?
- ((str[x] & 0xdf) - 'A')+10 : (str[x] - '0'));
- digit *= 16;
-
- ++x;
- digit += (str[x] >= 'A' ?
- ((str[x] & 0xdf) - 'A')+10 : (str[x] - '0'));
-
- str[y] = digit;
- }
- else if(str[x] == '+') {
- str[y] = ' ';
- } else {
- str[y] = str[x];
- }
- x++;
- y++;
- }
- str[y] = '\0';
-}
-
-
-/* Return the value of a POSTed variable, or NULL if none was sent. */
-char *
-dsgw_get_cgi_var(char *varname, int required)
-{
- register int x = 0;
- int len = strlen(varname);
- char *ans = NULL;
-
- while(formvars != NULL && formvars[x]) {
- /* We want to get rid of the =, so len, len+1 */
- if((!strncmp(formvars[x], varname, len)) &&
- (*(formvars[x]+len) == '=')) {
- ans = dsgw_ch_strdup(formvars[x] + len + 1);
- if(!strcmp(ans, "")) {
- free(ans);
- ans = NULL;
- }
- break;
- } else
- x++;
- }
-
- if ( required == DSGW_CGIVAR_REQUIRED && ans == NULL ) {
- char errbuf[ 256 ];
- PR_snprintf( errbuf, sizeof(errbuf),
- XP_GetClientStr(DBT_missingFormDataElement100s_), varname );
- dsgw_error( DSGW_ERR_BADFORMDATA, errbuf, DSGW_ERROPT_EXIT, 0, NULL );
- }
-
- return ans;
-}
-
-
-/*
- * Return integer equivalent of POSTed value. If no variable POSTed,
- * return defval.
- */
-int
-dsgw_get_int_var( char *varname, int required, int defval )
-{
- char *val;
- int rc;
-
- if (( val = dsgw_get_cgi_var( varname, required )) == NULL ) {
- rc = defval;
- } else {
- rc = atoi( val );
- free( val );
- }
-
- return( rc );
-}
-
-
-/*
- * Return non-zero if POSTed variable is "true" or "yes". If !required
- * and no variable POSTed, return defval.
- */
-int
-dsgw_get_boolean_var( char *varname, int required, int defval )
-{
- char *val;
- int rc;
-
- if (( val = dsgw_get_cgi_var( varname, required )) == NULL ) {
- rc = defval;
- } else {
- rc = ( strcasecmp( val, "true" ) == 0 ||
- strcasecmp( val, "yes" ) == 0 );
- free( val );
- }
-
- return( rc );
-}
-
-
-/*
- * If a CGI variable named "varname_escaped" was POST'd, unescape it and
- * return its value.
- * Otherwise if "varname" is not NULL and a CGI variable called "varname"
- * was POST'd, return its value.
- * Otherwise return NULL.
- */
-char *
-dsgw_get_escaped_cgi_var( char *varname_escaped, char *varname, int required )
-{
- char *val;
-
- if (( val = dsgw_get_cgi_var( varname_escaped,
- ( varname == NULL ) ? required: DSGW_CGIVAR_OPTIONAL )) != NULL ) {
- dsgw_form_unescape( val );
- } else if ( varname != NULL ) {
- val = dsgw_get_cgi_var( varname, required );
- }
-
- return( val );
-}
-
-
-/* Convert the input from stdin to a usable variable vector. */
-static char **
-dsgw_string_to_vec(char *in)
-{
- char **ans;
- int vars = 0;
- register int x = 0;
- char *tmp;
-
- while(in[x])
- if(in[x++]=='=')
- vars++;
-
- ans = (char **) dsgw_ch_malloc((sizeof(char *)) * (vars+1));
- if (ans) {
- x=0;
- /* strtok() is not MT safe, but it is okay to call here because it is used in monothreaded env */
- tmp = strtok(in, "&");
- if (tmp && *tmp && strchr(tmp, '=')) {
- ans[x]=dsgw_ch_strdup(tmp);
- dsgw_form_unescape(ans[x++]);
-
- while((x <= vars) && (tmp = strtok(NULL, "&"))) {
- if ( strchr( tmp, '=' ) == NULL ) {
- break;
- }
- ans[x] = dsgw_ch_strdup(tmp);
- dsgw_form_unescape(ans[x++]);
- }
- }
- ans[x] = NULL;
- }
-
- return(ans);
-}
-
-
-/*
- * Step through all the CGI POSTed variables. A malloc'd copy of the variable
- * name is returned and *valuep is set to point to the value (not malloc'd).
- * If there are no more variables, NULL is returned.
- *
- * The first time this is called, *indexp should be zero. On subsequent
- * calls, pass the same indexp as on the first call.
- */
-char *
-dsgw_next_cgi_var( int *indexp, char **valuep )
-{
- char *name;
- int namelen;
-
- if ( formvars == NULL || formvars[ *indexp ] == NULL ) {
- return( NULL );
- }
-
- if (( *valuep = strchr( formvars[ *indexp ], '=' )) == NULL ) {
- namelen = strlen( formvars[ *indexp ] );
- } else {
- namelen = *valuep - formvars[ *indexp ];
- ++(*valuep);
- }
- name = dsgw_ch_malloc( namelen + 1 );
- memcpy( name, formvars[ *indexp ], namelen );
- name[ namelen ] = '\0';
-
- *indexp += 1;
-
- return( name );
-}
-
-/*
- * converts a buffer of characters to/from UTF8 from/to a native charset
- * the given converter will handle the native charset
- * returns 0 if not all of source was converted, 1 if all of source
- * was converted, -1 upon error
- * all of source will be converted if there is enough room in dest to contain
- * the entire conversion, or if dest is null and we are malloc'ing space for dest
- */
-int
-dsgw_convert(
- int direction, /* false for native->utf8, true for utf8->native */
- UConverter *nativeConv, /* convert from/to native charset */
- char **dest, /* *dest is the destination buffer - if *dest == NULL, it will be malloced */
- size_t destSize, /* size of dest buffer (ignored if *dest == NULL) */
- size_t *nDest, /* number of chars written to dest */
- const char *source, /* source buffer to convert - either in native encoding (from) or utf8 (to) */
- size_t sourceSize, /* size of source buffer - if 0, assume source is NULL terminated */
- size_t *nSource, /* number of chars read from source buffer */
- UErrorCode *pErrorCode /* will be reset each time through */
-)
-{
-#define CHUNK_SIZE 1024
- UChar pivotBuffer[CHUNK_SIZE];
- UChar *pivot, *pivot2;
- static UConverter *utf8Converter = NULL;
- UConverter *inConverter, *outConverter;
- char *myDest;
- const char *mySource;
- const char *destLimit;
- const char *sourceLimit;
- int destAlloc = 0; /* set to true if we allocated *dest */
-
- *pErrorCode = U_ZERO_ERROR;
-
- if(sourceSize<0 || source==NULL || nDest==NULL || nSource==NULL)
- {
- *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
- return -1;
- }
-
- *nSource = 0;
- *nDest = 0;
-
- /* if source size is 0, assume source is null terminated and use strlen */
- if(sourceSize==0) {
- sourceSize = strlen(source);
- }
-
- /* create the converters */
- if (!utf8Converter) {
- utf8Converter = ucnv_open(UNICODE_ENCODING_UTF_8, pErrorCode);
- if(U_FAILURE(*pErrorCode)) {
- return -1;
- }
- }
- /* reset utf8Converter if done or error */
-
- if (direction) {
- inConverter = utf8Converter; /* source is utf8 */
- outConverter = nativeConv; /* dest is native charset */
- } else {
- inConverter = nativeConv; /* source is native charset */
- outConverter = utf8Converter; /* dest is utf8 */
- }
-
- /* if dest is NULL, allocate space for it - may be reallocated later */
- if (!*dest) {
- /* good approximation of size is n chars in source * max dest char size */
- destSize = ucnv_getMaxCharSize(outConverter) * sourceSize;
- *dest = dsgw_ch_malloc(destSize);
- destAlloc = 1;
- }
-
- /* set up the other variables */
- mySource = source;
- sourceLimit = source + sourceSize;
- pivot = pivot2 = pivotBuffer;
- myDest = *dest;
- destLimit = *dest + destSize;
-
- /*
- * loops until the input buffer is completely consumed
- * or an error is encountered;
- * first we convert from inConverter codepage to Unicode
- * then from Unicode to outConverter codepage
- */
- do {
- pivot = pivotBuffer;
- ucnv_toUnicode(inConverter,
- &pivot, pivotBuffer + CHUNK_SIZE,
- &mySource, sourceLimit,
- NULL,
- TRUE,
- pErrorCode);
-
- /* U_BUFFER_OVERFLOW_ERROR only means that the pivot buffer is full */
- if(U_SUCCESS(*pErrorCode) || (*pErrorCode == U_BUFFER_OVERFLOW_ERROR)) {
- pivot2 = pivotBuffer;
-
- /* convert and write bytes from the pivot buffer to the dest -
- if dest is allocated and we run out of space in dest, grow
- dest and try again - otherwise, just bail out and let the
- caller know that their dest buffer is full and they need
- to try again */
- do {
- *pErrorCode = U_ZERO_ERROR;
- ucnv_fromUnicode(outConverter,
- &myDest, destLimit,
- (const UChar **)&pivot2, pivot,
- NULL,
- (UBool)(mySource == sourceLimit),
- pErrorCode);
-
- /* we overflowed dest and dest is allocated, so let's increase
- the dest size */
- if ((*pErrorCode == U_BUFFER_OVERFLOW_ERROR) && destAlloc) {
- /* figure out where myDest was pointing */
- size_t myDestOffset = myDest - *dest;
- /* probably don't need this much more room . . . */
- destSize += CHUNK_SIZE;
- /* realloc *dest for new size */
- *dest = dsgw_ch_realloc(*dest, destSize);
- /* reset myDest in new *dest */
- myDest = *dest + myDestOffset;
- /* set new destLimit */
- destLimit = *dest + destSize;
- } else {
- break; /* skip it */
- }
- } while(*pErrorCode == U_BUFFER_OVERFLOW_ERROR);
- /*
- * If this overflows the fixed size dest, then we must stop
- * converting and return what we already have
- * in this case, pErrorCode will be buffer overflow error because
- * we have overflowed the dest buffer
- * the outer while loop will break because !U_SUCCESS
- */
- }
- } while(U_SUCCESS(*pErrorCode) && mySource != sourceLimit);
-
- *nSource = mySource - source; /* n chars read from source */
- *nDest = myDest - *dest; /* n chars written to dest */
-
- if (U_SUCCESS(*pErrorCode) && mySource == sourceLimit) {
- /* reset internal converter */
- ucnv_reset(utf8Converter);
- return 1; /* converted entire string */
- }
-
- if (mySource != sourceLimit) {
- /* not done with conversion yet */
- /* no reset here - preserve state for next call */
- return 0;
- }
-
- /* error */
- ucnv_reset(utf8Converter);
- return -1;
-}