示例#1
0
/// Parses GET or POST-style variable data.
/// Saves to internal variable structure using HTTP::Parser::SetVar.
void HTTP::Parser::parseVars(std::string data) {
  std::string varname;
  std::string varval;
  // position where a part start (e.g. after &)
  size_t pos = 0;
  while (pos < data.length()) {
    size_t nextpos = data.find('&', pos);
    if (nextpos == std::string::npos) {
      nextpos = data.length();
    }
    size_t eq_pos = data.find('=', pos);
    if (eq_pos < nextpos) {
      // there is a key and value
      varname = data.substr(pos, eq_pos - pos);
      varval = data.substr(eq_pos + 1, nextpos - eq_pos - 1);
    } else {
      // no value, only a key
      varname = data.substr(pos, nextpos - pos);
      varval.clear();
    }
    SetVar(urlunescape(varname), urlunescape(varval));
    if (nextpos == std::string::npos) {
      // in case the string is gigantic
      break;
    }
    // erase &
    pos = nextpos + 1;
  }
}
示例#2
0
文件: ldaptest.c 项目: tjyang/abmon
int add_ldap_test(testitem_t *t)
{
#ifdef BBGEN_LDAP
    ldap_data_t *req;
    LDAPURLDesc *ludp;
    char *urltotest;

    /*
     * t->testspec containts the full testspec
     * We need to remove any URL-encoding.
     */
    urltotest = urlunescape(t->testspec);

    if (ldap_url_parse(urltotest, &ludp) != 0) {
        errprintf("Invalid LDAP URL %s\n", t->testspec);
        return 1;
    }

    /* Allocate the private data and initialize it */
    t->privdata = (void *) malloc(sizeof(ldap_data_t));
    req = (ldap_data_t *) t->privdata;
    req->ldapdesc = (void *) ludp;
    req->usetls = (strncmp(urltotest, "ldaps:", 6) == 0);
#ifdef BBGEN_LDAP_USESTARTTLS
    if (req->usetls && (ludp->lud_port == LDAPS_PORT)) {
        dbgprintf("Forcing port %d for ldaps with STARTTLS\n", LDAP_PORT );
        ludp->lud_port = LDAP_PORT;
    }
#endif
    req->ldapstatus = 0;
    req->output = NULL;
    req->ldapcolor = -1;
    req->faileddeps = NULL;
    req->duration.tv_sec = req->duration.tv_nsec = 0;
    req->certinfo = NULL;
    req->certexpires = 0;
#endif

    return 0;
}
示例#3
0
/*
 * Get an environment variable (eg: QUERY_STRING) and do CGI decoding of it.
 */
char *urldecode(char *envvar)
{
	if (xgetenv(envvar) == NULL) return NULL;

	return urlunescape(xgetenv(envvar));
}
示例#4
0
/*
 * Parse a URL into components, following the guidelines in RFC 1808.
 * This fills out a urlelem_t struct with the elements, and also
 * constructs a canonical form of the URL.
 */
void parse_url(char *inputurl, urlelem_t *url)
{

	char *tempurl;
	char *fragment = NULL;
	char *netloc;
	char *startp, *p;
	int haveportspec = 0;
	char *canonurl;
	int canonurllen;

	memset(url, 0, sizeof(urlelem_t));
	url->scheme = url->host = url->relurl = "";

	/* Get a temp. buffer we can molest */
	tempurl = strdup(inputurl);

	/* First cut off any fragment specifier */
	fragment = strchr(tempurl, '#'); if (fragment) *fragment = '\0';

	/* Get the scheme (protocol) */
	startp = tempurl;
	p = strchr(startp, ':');
	if (p) {
		*p = '\0';
		if (strncmp(startp, "https", 5) == 0) {
			url->scheme = "https";
			url->port = 443;
			if (strlen(startp) > 5) url->schemeopts = strdup(startp+5);
		} else if (strncmp(startp, "http", 4) == 0) {
			url->scheme = "http";
			url->port = 80;
			if (strlen(startp) > 4) url->schemeopts = strdup(startp+4);
		} else if (strcmp(startp, "ftp") == 0) {
			url->scheme = "ftp";
			url->port = 21;
		} else if (strcmp(startp, "ldap") == 0) {
			url->scheme = "ldap";
			url->port = 389;
		} else if (strcmp(startp, "ldaps") == 0) {
			url->scheme = "ldaps";
			url->port = 389; /* ldaps:// URL's are non-standard, and must use port 389+STARTTLS */
		}
		else {
			/* Unknown scheme! */
			errprintf("Unknown URL scheme '%s' in URL '%s'\n", startp, inputurl);
			url->scheme = strdup(startp);
			url->port = 0;
		}
		startp = (p+1);
	}
	else {
		errprintf("Malformed URL - no 'scheme:' in '%s'\n", inputurl);
		url->parseerror = 1;
		return;
	}

	if (strncmp(startp, "//", 2) == 0) {
		startp += 2;
		netloc = startp;

		p = strchr(startp, '/');
		if (p) {
			*p = '\0';
			startp = (p+1);
		}
		else startp += strlen(startp);
	}
	else {
		errprintf("Malformed URL missing '//' in '%s'\n", inputurl);
		url->parseerror = 2;
		return;
	}

	/* netloc is [username:password@]hostname[:port][=forcedIP] */
	p = strchr(netloc, '@');
	if (p) {
		*p = '\0';
		url->auth = strdup(urlunescape(netloc));
		netloc = (p+1);
	}
	p = strchr(netloc, '=');
	if (p) {
		url->ip = strdup(p+1);
		*p = '\0';
	}
	p = strchr(netloc, ':');
	if (p) {
		haveportspec = 1;
		*p = '\0';
		url->port = atoi(p+1);
	}

	url->host = strdup(netloc);
	if (url->port == 0) {
		struct servent *svc = getservbyname(url->scheme, NULL);
		if (svc) url->port = ntohs(svc->s_port);
		else {
			errprintf("Unknown scheme (no port) '%s'\n", url->scheme);
			url->parseerror = 3;
			return;
		}
	}

	if (fragment) *fragment = '#';
	url->relurl = malloc(strlen(startp) + 2);
	sprintf(url->relurl, "/%s", startp);

	if (url->auth == NULL) {
		/* See if we have it in the .netrc list */
		loginlist_t *walk;

		load_netrc();
		for (walk = loginhead; (walk && (strcmp(walk->host, url->host) != 0)); walk = walk->next) ;
		if (walk) url->auth = walk->auth;
	}

	/* Build the canonical form of this URL, free from all BB'isms */
	canonurllen = 1;
	canonurllen += strlen(url->scheme)+3;	/* Add room for the "://" */
	canonurllen += strlen(url->host);
	canonurllen += 6; 			/* Max. length of a port spec. */
	canonurllen += strlen(url->relurl);

	p = canonurl = (char *)malloc(canonurllen);
	p += sprintf(p, "%s://", url->scheme);
	/*
	 * Dont include authentication here, since it 
	 * may show up in clear text on the info page.
	 * And it is not used in URLs to access the site.
	 * if (url->auth) p += sprintf(p, "%s@", url->auth);
	 */
	p += sprintf(p, "%s", url->host);
	if (haveportspec) p += sprintf(p, ":%d", url->port);
	p += sprintf(p, "%s", url->relurl);
	url->origform = canonurl;

	xfree(tempurl);
	return;
}
示例#5
0
文件: ldaptest.c 项目: tjyang/cpam
int add_ldap_test(testitem_t *t)
{
#ifdef HAVE_LDAP
	testitem_t *basecheck;
	ldap_data_t *req;
	LDAPURLDesc *ludp;
	char *urltotest;
	int badurl;

	basecheck = (testitem_t *)t->privdata;

	/* 
	 * t->testspec containts the full testspec
	 * We need to remove any URL-encoding.
	 */
	urltotest = urlunescape(t->testspec);
	badurl = (ldap_url_parse(urltotest, &ludp) != 0);

	/* Allocate the private data and initialize it */
	t->privdata = (void *) calloc(1, sizeof(ldap_data_t)); 
	req = (ldap_data_t *) t->privdata;
	req->ldapdesc = (void *) ludp;
	req->usetls = (strncmp(urltotest, "ldaps:", 6) == 0);
	if (req->usetls && (ludp->lud_port == LDAPS_PORT)) {
		dbgprintf("Forcing port %d for ldaps with STARTTLS\n", LDAP_PORT );
		ludp->lud_port = LDAP_PORT;
	}
	req->ldapstatus = 0;
	req->output = NULL;
	req->ldapcolor = -1;
	req->faileddeps = NULL;
	req->duration.tv_sec = req->duration.tv_nsec = 0;
	req->certinfo = NULL;
	req->certissuer = NULL;
	req->certexpires = 0;
	req->certkeysz = 0;
	req->skiptest = 0;

	if (badurl) {
		errprintf("Invalid LDAP URL %s\n", t->testspec);
		req->skiptest = 1;
		req->ldapstatus = XYMON_LDAP_BINDFAIL;
		req->output = "Cannot parse LDAP URL";
	}

	/*
	 * At this point, the plain TCP checks have already run.
	 * So we know from the test found in t->privdata whether
	 * the LDAP port is open.
	 * If it is not open, then dont run this check.
	 */
	if (basecheck->open == 0) {
		/* Cannot connect to LDAP port. */
		req->skiptest = 1;
		req->ldapstatus = XYMON_LDAP_BINDFAIL;
		req->output = "Cannot connect to server";
	}

#endif

	return 0;
}
示例#6
0
文件: ldaptest.c 项目: tjyang/cpam
int main(int argc, char *argv[])
{
	testitem_t item;
	testedhost_t host;
	service_t ldapservice;
	int argi = 1;
	int ldapdebug = 0;

	while ((argi < argc) && (strncmp(argv[argi], "--", 2) == 0)) {
		if (strcmp(argv[argi], "--debug") == 0) {
			debug = 1;
		}
		else if (strncmp(argv[argi], "--ldapdebug=", strlen("--ldapdebug=")) == 0) {
			char *p = strchr(argv[argi], '=');
			ldapdebug = atoi(p+1);
		}
		argi++;
	}

	/* For testing, dont crash in sendmsg when no XYMSRV defined */
	dontsendmessages = 1;
	if (xgetenv("XYMSRV") == NULL) putenv("XYMSRV=127.0.0.1");

	memset(&item, 0, sizeof(item));
	memset(&host, 0, sizeof(host));
	memset(&ldapservice, 0, sizeof(ldapservice));

	ldapservice.portnum = 389;
	ldapservice.testname = "ldap";
	ldapservice.namelen = strlen(ldapservice.testname);
	ldapservice.items = &item;

	item.host = &host;
	item.service = &ldapservice;
	item.dialup = item.reverse = item.silenttest = item.alwaystrue = 0;
	item.testspec = urlunescape(argv[argi]);

	host.firstldap = &item;
	host.hostname = "ldaptest.xymon";
	host.ldapuser = NULL;
	host.ldappasswd = NULL;

	init_ldap_library();

	if (ldapdebug) {
#if defined(LBER_OPT_DEBUG_LEVEL) && defined(LDAP_OPT_DEBUG_LEVEL)
		ber_set_option(NULL, LBER_OPT_DEBUG_LEVEL, &ldapdebug);
		ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, &ldapdebug);
#else
		printf("LDAP library does not support change of debug level\n");
#endif
	}

	if (add_ldap_test(&item) == 0) {
		run_ldap_tests(&ldapservice, 0, 10);
		combo_start();
		send_ldap_results(&ldapservice, &host, "", 0);
		combo_end();
	}

	shutdown_ldap_library();
	return 0;
}
示例#7
0
/// Attempt to read a whole HTTP response or request from a data buffer.
/// If succesful, fills its own fields with the proper data and removes the response/request
/// from the data buffer.
/// \param HTTPbuffer The data buffer to read from.
/// \return True on success, false otherwise.
bool HTTP::Parser::parse(std::string & HTTPbuffer) {
  size_t f;
  std::string tmpA, tmpB, tmpC;
  /// \todo Make this not resize HTTPbuffer in parts, but read all at once and then remove the entire request, like doxygen claims it does?
  while (!HTTPbuffer.empty()) {
    if (!seenHeaders) {
      f = HTTPbuffer.find('\n');
      if (f == std::string::npos) return false;
      tmpA = HTTPbuffer.substr(0, f);
      if (f + 1 == HTTPbuffer.size()) {
        HTTPbuffer.clear();
      } else {
        HTTPbuffer.erase(0, f + 1);
      }
      while (tmpA.find('\r') != std::string::npos) {
        tmpA.erase(tmpA.find('\r'));
      }
      if (!seenReq) {
        seenReq = true;
        f = tmpA.find(' ');
        if (f != std::string::npos) {
          if (tmpA.substr(0, 4) == "HTTP") {
            protocol = tmpA.substr(0, f);
            tmpA.erase(0, f + 1);
            f = tmpA.find(' ');
            if (f != std::string::npos) {
              url = tmpA.substr(0, f);
              tmpA.erase(0, f + 1);
              method = tmpA;
              if (url.find('?') != std::string::npos) {
                parseVars(url.substr(url.find('?') + 1)); //parse GET variables
                url.erase(url.find('?'));
              }
              url = urlunescape(url);
            } else {
              seenReq = false;
            }
          } else {
            method = tmpA.substr(0, f);
            tmpA.erase(0, f + 1);
            f = tmpA.find(' ');
            if (f != std::string::npos) {
              url = tmpA.substr(0, f);
              tmpA.erase(0, f + 1);
              protocol = tmpA;
              if (url.find('?') != std::string::npos) {
                parseVars(url.substr(url.find('?') + 1)); //parse GET variables
                url.erase(url.find('?'));
              }
              url = urlunescape(url);
            } else {
              seenReq = false;
            }
          }
        } else {
          seenReq = false;
        }
      } else {
        if (tmpA.size() == 0) {
          seenHeaders = true;
          body.clear();
          if (GetHeader("Content-Length") != "") {
            length = atoi(GetHeader("Content-Length").c_str());
            if (body.capacity() < length) {
              body.reserve(length);
            }
          }
          if (GetHeader("Transfer-Encoding") == "chunked") {
            getChunks = true;
            doingChunk = 0;
          }
        } else {
          f = tmpA.find(':');
          if (f == std::string::npos) continue;
          tmpB = tmpA.substr(0, f);
          tmpC = tmpA.substr(f + 1);
          SetHeader(tmpB, tmpC);
        }
      }
    }
    if (seenHeaders) {
      if (length > 0) {
        if (headerOnly) {
          return true;
        }
        unsigned int toappend = length - body.length();
        if (toappend > 0) {
          body.append(HTTPbuffer, 0, toappend);
          HTTPbuffer.erase(0, toappend);
        }
        if (length == body.length()) {
          parseVars(body); //parse POST variables
          return true;
        } else {
          return false;
        }
      } else {
        if (getChunks) {
          if (headerOnly) {
            return true;
          }
          if (doingChunk) {
            unsigned int toappend = HTTPbuffer.size();
            if (toappend > doingChunk) {
              toappend = doingChunk;
            }
            body.append(HTTPbuffer, 0, toappend);
            HTTPbuffer.erase(0, toappend);
            doingChunk -= toappend;
          } else {
            f = HTTPbuffer.find('\n');
            if (f == std::string::npos) return false;
            tmpA = HTTPbuffer.substr(0, f);
            while (tmpA.find('\r') != std::string::npos) {
              tmpA.erase(tmpA.find('\r'));
            }
            unsigned int chunkLen = 0;
            if (!tmpA.empty()) {
              for (unsigned int i = 0; i < tmpA.size(); ++i) {
                chunkLen = (chunkLen << 4) | unhex(tmpA[i]);
              }
              if (chunkLen == 0) {
                getChunks = false;
                return true;
              }
              doingChunk = chunkLen;
            }
            if (f + 1 == HTTPbuffer.size()) {
              HTTPbuffer.clear();
            } else {
              HTTPbuffer.erase(0, f + 1);
            }
          }
          return false;
        } else {
          return true;
        }
      }
    }
  }
  return false; //empty input
} //HTTPReader::parse
示例#8
0
文件: cgi.c 项目: Kotty666/xymon
cgidata_t *cgi_request(void)
{
	char *method = NULL;
	char *reqdata = NULL;
	char *conttype = NULL;
        char *token;
	cgidata_t *head = NULL, *tail = NULL;

	cgi_error_text = NULL;
	cgi_method = CGI_OTHER;

	method = getenv("REQUEST_METHOD");
	if (!method) {
		lcgi_error("CGI violation - no REQUEST_METHOD\n");
		return NULL;
	}

	conttype = getenv("CONTENT_TYPE");

	if (strcasecmp(method, "POST") == 0) {
		char *contlen = getenv("CONTENT_LENGTH");
		int postsize = 0;

		cgi_method = CGI_POST;

		if (contlen) {
			postsize = atoi(contlen);
		}
		else {
			lcgi_error("CGI violation - no CONTENT_LENGTH\n");
			return NULL;
		}

		if (postsize < MAX_REQ_SIZE) {
			size_t n;

			reqdata = (char *)malloc(postsize+1);
			n = fread(reqdata, 1, postsize, stdin);
			if (n < postsize) {
				lcgi_error("Error reading POST data\n");
				return NULL;
			}
			reqdata[n] = '\0';
		}
		else {
			lcgi_error("Request too large\n");
			return NULL;
		}
	}
	else if (strcasecmp(method, "GET") == 0) {
		char *q = getenv("QUERY_STRING");

		cgi_method = CGI_GET;

		if (q) {
			if (strlen(q) < MAX_REQ_SIZE) {
				reqdata = strdup(q);
			}
			else {
				lcgi_error("Request too large\n");
				return NULL;
			}
		}
		else {
			/* This is OK - we may not have any query */
			return NULL;
		}
	}

	dbgprintf("CGI: Request method='%s', data='%s'\n", method, textornull(reqdata));

	if ((cgi_method == CGI_GET) || (conttype && (strcasecmp(conttype, "application/x-www-form-urlencoded") == 0))) {
		token = strtok(reqdata, "&");

		while (token) {
			cgidata_t *newitem = (cgidata_t *)calloc(1, sizeof(cgidata_t));
			char *val;

			val = strchr(token, '='); 
			if (val) { 
				*val = '\0'; 
				val = urlunescape(val+1);
			}

			newitem->name = strdup(token);
			newitem->value = strdup(val ? val : "");

			if (!tail) {
				head = newitem;
			}
			else {
				tail->next = newitem;
			}
			tail = newitem;

			token = strtok(NULL, "&");
		}
	}
	else if ((cgi_method == CGI_POST) && (conttype && (strcasecmp(conttype, "multipart/form-data") == 0))) {
		char *bol, *eoln, *delim;
		char eolnchar = '\n';
		char *currelembegin = NULL, *currelemend = NULL;
		cgidata_t *newitem = NULL;
		
		delim = reqdata;
		eoln = strchr(delim, '\n'); if (!eoln) return NULL;
		*eoln = '\0'; delim = strdup(reqdata); *eoln = '\n';
		if (*(delim + strlen(delim) - 1) == '\r') {
			eolnchar = '\r';
			*(delim + strlen(delim) - 1) = '\0';
		}

		bol = reqdata;
		do {
			eoln = strchr(bol, eolnchar); if (eoln) *eoln = '\0';
			if (strncmp(bol, delim, strlen(delim)) == 0) {
				if (newitem && currelembegin && (currelemend >= currelembegin)) {
					/* Finish off the current item */
					char savech;
					
					savech = *currelemend;
					*currelemend = '\0';
					newitem->value = strdup(currelembegin);
					*currelemend = savech;
					currelembegin = currelemend = NULL;
				}

				if (strcmp(bol+strlen(delim), "--") != 0) {
					/* New element */
					newitem = (cgidata_t *)calloc(1, sizeof(cgidata_t));

					if (!tail) head = newitem; else tail->next = newitem;
					tail = newitem;
				}
				else {
					/* No more elements, end of input */
					newitem = NULL;
					bol = NULL;
					continue;
				}
			}
			else if (newitem && (strncasecmp(bol, "Content-Disposition:", 20) == 0)) {
				char *tok;

				tok = strtok(bol, ";\t ");
				while (tok) {
					if (strncasecmp(tok, "name=", 5) == 0) {
						char *name;

						name = tok+5; 
						if (*name == '\"') {
							name++;
							*(name + strlen(name) - 1) = '\0';
						}
						newitem->name = strdup(name);
					}
					else if (strncasecmp(tok, "filename=", 9) == 0) {
						char *filename;

						filename = tok+9; 
						if (*filename == '\"') {
							filename++;
							*(filename + strlen(filename) - 1) = '\0';
						}
						newitem->filename = strdup(filename);
					}

					tok = strtok(NULL, ";\t ");
				}
			}
			else if (newitem && (strncasecmp(bol, "Content-Type:", 12) == 0)) {
			}
			else if (newitem && !currelembegin && (*bol == '\0')) {
				/* End of headers for one element */
				if (eoln) {
					currelembegin = eoln+1;
					if ((eolnchar == '\r') && (*currelembegin == '\n')) currelembegin++;
				}

				currelemend = currelembegin;
			}
			else if (newitem && currelembegin) {
				currelemend = (eoln ? eoln+1 : bol + strlen(bol));
			}

			if (eoln) {
				bol = eoln+1;
				if ((eolnchar == '\r') && (*bol == '\n')) bol++;
			}
			else {
				bol = NULL;
			}
		} while (bol && (*bol));

		if (newitem) {
			if (!newitem->name) newitem->name = "";
			if (!newitem->value) newitem->value = "";
		}
	}
	else {
		/* Raw data - return a single record to caller */
		head = (cgidata_t *)calloc(1, sizeof(cgidata_t));
		head->name = strdup("");
		head->value = reqdata ? strdup(reqdata) : NULL;
	}

	if (reqdata) xfree(reqdata);

	return head;
}