예제 #1
0
int uri_worker_map_load(jk_uri_worker_map_t *uw_map,
                        jk_logger_t *l)
{
    int rc = JK_FALSE;
    jk_map_t *map;

    jk_map_alloc(&map);
    if (jk_map_read_properties(map, NULL, uw_map->fname, &uw_map->modified,
                               JK_MAP_HANDLE_NORMAL, l)) {
        int i;
        if (JK_IS_DEBUG_LEVEL(l))
            jk_log(l, JK_LOG_DEBUG,
                   "Loading urimaps from %s with reload check interval %d seconds",
                   uw_map->fname, uw_map->reload);
        uri_worker_map_clear(uw_map, l);
        for (i = 0; i < jk_map_size(map); i++) {
            const char *u = jk_map_name_at(map, i);
            const char *w = jk_map_value_at(map, i);
            /* Multiple mappings like :
             * /servlets-examples|/ *
             * will create two mappings:
             * /servlets-examples
             * and:
             * /servlets-examples/ *
             */
            if (strchr(u, '|')) {
                char *s, *r = strdup(u);
                s = strchr(r, '|');
                *(s++) = '\0';
                /* Add first mapping */
                if (!uri_worker_map_add(uw_map, r, w, SOURCE_TYPE_URIMAP, l)) {
                    jk_log(l, JK_LOG_ERROR,
                    "invalid mapping rule %s->%s", r, w);
                }
                for (; *s; s++)
                   *(s - 1) = *s;
                *(s - 1) = '\0';
                /* add second mapping */
                if (!uri_worker_map_add(uw_map, r, w, SOURCE_TYPE_URIMAP, l)) {
                    jk_log(l, JK_LOG_ERROR,
                    "invalid mapping rule %s->%s", r, w);
                }
                free(r);
            }
            else if (!uri_worker_map_add(uw_map, u, w, SOURCE_TYPE_URIMAP, l)) {
                jk_log(l, JK_LOG_ERROR,
                       "invalid mapping rule %s->%s",
                       u, w);
            }
        }
        uw_map->checked = time(NULL);
        if (JK_IS_DEBUG_LEVEL(l))
            uri_worker_map_dump(uw_map, "after file load", l);
        rc = JK_TRUE;
    } else {
        jk_log(l, JK_LOG_ERROR, "Failed to load uri_worker_map file %s (errno=%d, err=%s).", uw_map->fname, errno, strerror(errno));
    }
    jk_map_free(&map);
    return rc;
}
예제 #2
0
static int JK_METHOD Read(jk_ws_service_t * s, void *bytes, unsigned len, unsigned *countp)
{
	DEBUG(("Read(%p, %p, %u, %p)\n", s, bytes, len, countp));
	jk_log(logger, JK_LOG_DEBUG, "Into jk_ws_service_t::Read\n");

	if (s && s->ws_private && bytes && countp)
	{
		private_ws_t *p = s->ws_private;

		/* Copy data from Domino's buffer. Although it seems slightly
		 * improbably we're believing that Domino always buffers the
		 * entire request in memory. Not properly tested yet.
		 */
		if (len > p->reqSize) len = p->reqSize;
		memcpy(bytes, p->reqBuffer, len);
		p->reqBuffer += len;
		p->reqSize -= len;
		*countp = len;
		return JK_TRUE;
	}

	jk_log(logger, JK_LOG_ERROR, "jk_ws_service_t::Read, NULL parameters\n");

	return JK_FALSE;
}
예제 #3
0
bool FilterAgentRequest::setHeader(string name, string value) {

	if (this->NotificationType != SF_NOTIFY_PREPROC_HEADERS) {
		jk_log(logger, JK_LOG_ERROR, "Unsupported Notification Type %d", this->NotificationType);
		return false;
	}

	HTTP_FILTER_PREPROC_HEADERS * pPPH = (HTTP_FILTER_PREPROC_HEADERS *) this->pvNotification;

    string hdr = name + ":";
	string hdrv = value + "";
    int rc = pPPH->SetHeader(this->pfc, const_cast<char*>(hdr.c_str()), const_cast<char*>(hdrv.c_str()));
	if (!rc) {
		DWORD dwError = GetLastError();

		if (rc == ERROR_INVALID_PARAMETER ) {
			jk_log(logger, JK_LOG_ERROR, "SetHeader %s=[%s] failed = %d (%x), Invalid Parameter", 
				name.c_str(), value.c_str(), dwError, dwError);
		} else if (rc == ERROR_NOT_SUPPORTED) {
			jk_log(logger, JK_LOG_ERROR, "SetHeader %s=[%s] failed = %d (%x), Not supported", 
				name.c_str(), value.c_str(), dwError, dwError);
		} else {
			jk_log(logger, JK_LOG_ERROR, "SetHeader %s=[%s] failed = %d (%x), Unknown", 
				name.c_str(), value.c_str(), dwError, dwError);

		}
		return false;

	}

	return true;

}
예제 #4
0
static void extension_fix_session(jk_pool_t *p, const char *name, jk_worker_t *jw,
                                  rule_extension_t *extensions, jk_logger_t *l)
{
    if (jw->type != JK_LB_WORKER_TYPE && extensions->session_cookie) {
        jk_log(l, JK_LOG_WARNING,
                "Worker %s is not of type lb, extension "
                JK_UWMAP_EXTENSION_SESSION_COOKIE " for %s ignored",
                name, extensions->session_cookie);
    }
    if (jw->type != JK_LB_WORKER_TYPE && extensions->session_path) {
        jk_log(l, JK_LOG_WARNING,
                "Worker %s is not of type lb, extension "
                JK_UWMAP_EXTENSION_SESSION_PATH " for %s ignored",
                name, extensions->session_path);
    }
    if (jw->type != JK_LB_WORKER_TYPE && extensions->set_session_cookie) {
        jk_log(l, JK_LOG_WARNING,
                "Worker %s is not of type lb, extension "
                JK_UWMAP_EXTENSION_SET_SESSION_COOKIE " for %s ignored",
                name, extensions->set_session_cookie ? "'true'" : "'false'");
    }
    if (jw->type != JK_LB_WORKER_TYPE && extensions->session_cookie_path) {
        jk_log(l, JK_LOG_WARNING,
                "Worker %s is not of type lb, extension "
                JK_UWMAP_EXTENSION_SESSION_COOKIE_PATH " for %s ignored",
                name, extensions->session_cookie_path);
    }
}
예제 #5
0
static int JK_METHOD Write(jk_ws_service_t *s, const void *bytes, unsigned len)
{
	DEBUG(("Write(%p, %p, %u)\n", s, bytes, len));
	jk_log(logger, JK_LOG_DEBUG, "Into jk_ws_service_t::Write\n");

	if (s && s->ws_private && bytes)
	{
		private_ws_t *p = s->ws_private;
		int errID, rc;

		/* Make sure the response has really started. I'm almost certain
		 * this isn't necessary, but it was in the ISAPI code, so it's in
		 * here too.
		 */
		if (!p->responseStarted)
			StartResponse(s, 200, NULL, NULL, NULL, 0);

		DEBUG(("Writing %d bytes of content\n", len));

		/* Send the data */
		if (len > 0)
			rc = p->context->WriteClient(p->context, (char *) bytes, len, 0, &errID);

		return JK_TRUE;
	}

	jk_log(logger, JK_LOG_ERROR, "jk_ws_service_t::Write, NULL parameters\n");

	return JK_FALSE;
}
예제 #6
0
int jk_is_input_event(jk_sock_t sd, int timeout, jk_logger_t *l)
{
    struct pollfd fds;
    int rc;
    int save_errno;
    char buf[DUMP_SINFO_BUF_SZ];

    JK_TRACE_ENTER(l);

    errno = 0;
    fds.fd = sd;
    fds.events = POLLIN;
    fds.revents = 0;

    do {
        rc = poll(&fds, 1, timeout);
    } while (rc < 0 && errno == EINTR);

    if (rc == 0) {
        if (JK_IS_DEBUG_LEVEL(l)) {
            jk_log(l, JK_LOG_DEBUG,
                   "timeout during poll on socket %d [%s] (timeout=%d)",
                   sd, jk_dump_sinfo(sd, buf, sizeof(buf)), timeout);
        }
        /* Timeout. Set the errno to timeout */
        errno = ETIMEDOUT;
        JK_TRACE_EXIT(l);
        return JK_FALSE;
    }
    else if (rc < 0) {
        save_errno = errno;
        if (JK_IS_DEBUG_LEVEL(l)) {
            jk_log(l, JK_LOG_DEBUG,
                   "error during poll on socket %d [%s] (errno=%d)",
                   sd, jk_dump_sinfo(sd, buf, sizeof(buf)), errno);
        }
        errno = save_errno;
        JK_TRACE_EXIT(l);
        return JK_FALSE;
    }
    if ((fds.revents & (POLLERR | POLLHUP))) {
        save_errno = fds.revents & (POLLERR | POLLHUP);
        if (JK_IS_DEBUG_LEVEL(l)) {
            jk_log(l, JK_LOG_DEBUG,
                   "error event during poll on socket %d [%s] (event=%d)",
                   sd, jk_dump_sinfo(sd, buf, sizeof(buf)), save_errno);
        }
        errno = save_errno;
        JK_TRACE_EXIT(l);
        return JK_FALSE;
    }
    errno = 0;
    JK_TRACE_EXIT(l);
    return JK_TRUE;
}
예제 #7
0
static int is_nomatch(jk_uri_worker_map_t *uw_map,
                      const char *uri, int match,
                      jk_logger_t *l)
{
    unsigned int i;
    const char *worker = IND_THIS(uw_map->maps)[match]->worker_name;

    JK_TRACE_ENTER(l);

    for (i = 0; i < IND_THIS(uw_map->size); i++) {
        uri_worker_record_t *uwr = IND_THIS(uw_map->maps)[i];

        /* Check only nomatch mappings */
        if (!(uwr->match_type & MATCH_TYPE_NO_MATCH) ||
            (uwr->match_type & MATCH_TYPE_DISABLED))
            continue;
        /* Check only matching workers */
        if (strcmp(uwr->worker_name, worker) &&
            strcmp(uwr->worker_name, "*"))
            continue;
        if (uwr->match_type & MATCH_TYPE_WILDCHAR_PATH) {
            /* Map is already sorted by context_len */
            if (jk_wildchar_match(uri, uwr->context,
#ifdef WIN32
                               0
#else
                               0
#endif
                               ) == 0) {
                    if (JK_IS_DEBUG_LEVEL(l))
                        jk_log(l, JK_LOG_DEBUG,
                               "Found a wildchar no match '%s=%s' source '%s'",
                               uwr->context, uwr->worker_name, uri_worker_map_get_source(uwr, l));
                    JK_TRACE_EXIT(l);
                    return JK_TRUE;
             }
        }
        else if (JK_STRNCMP(uwr->context, uri, uwr->context_len) == 0) {
            if (strlen(uri) == uwr->context_len) {
                if (JK_IS_DEBUG_LEVEL(l))
                    jk_log(l, JK_LOG_DEBUG,
                           "Found an exact no match '%s=%s' source '%s'",
                           uwr->context, uwr->worker_name, uri_worker_map_get_source(uwr, l));
                JK_TRACE_EXIT(l);
                return JK_TRUE;
            }
        }
    }

    JK_TRACE_EXIT(l);
    return JK_FALSE;
}
예제 #8
0
static int find_match(jk_uri_worker_map_t *uw_map,
                      const char *url, jk_logger_t *l)
{
    unsigned int i;

    JK_TRACE_ENTER(l);

    for (i = 0; i < IND_THIS(uw_map->size); i++) {
        uri_worker_record_t *uwr = IND_THIS(uw_map->maps)[i];

        /* Check for match types */
        if ((uwr->match_type & MATCH_TYPE_DISABLED) ||
            (uwr->match_type & MATCH_TYPE_NO_MATCH))
            continue;

        if (JK_IS_DEBUG_LEVEL(l))
            jk_log(l, JK_LOG_DEBUG, "Attempting to map context URI '%s=%s' source '%s'",
                   uwr->context, uwr->worker_name, uri_worker_map_get_source(uwr, l));

        if (uwr->match_type & MATCH_TYPE_WILDCHAR_PATH) {
            /* Map is already sorted by context_len */
            if (jk_wildchar_match(url, uwr->context,
#ifdef WIN32
                               0
#else
                               0
#endif
                               ) == 0) {
                    if (JK_IS_DEBUG_LEVEL(l))
                        jk_log(l, JK_LOG_DEBUG,
                               "Found a wildchar match '%s=%s'",
                               uwr->context, uwr->worker_name);
                    JK_TRACE_EXIT(l);
                    return i;
             }
        }
        else if (JK_STRNCMP(uwr->context, url, uwr->context_len) == 0) {
            if (strlen(url) == uwr->context_len) {
                if (JK_IS_DEBUG_LEVEL(l))
                    jk_log(l, JK_LOG_DEBUG,
                           "Found an exact match '%s=%s'",
                           uwr->context, uwr->worker_name);
                JK_TRACE_EXIT(l);
                return i;
            }
        }
    }

    JK_TRACE_EXIT(l);
    return -1;
}
예제 #9
0
int jk_is_input_event(jk_sock_t sd, int timeout, jk_logger_t *l)
{
    fd_set rset;
    struct timeval tv;
    int rc;
    int save_errno;
    char buf[DUMP_SINFO_BUF_SZ];

    JK_TRACE_ENTER(l);

    errno = 0;
    FD_ZERO(&rset);
    FD_SET(sd, &rset);
    tv.tv_sec = timeout / 1000;
    tv.tv_usec = (timeout % 1000) * 1000;

    do {
        rc = select((int)sd + 1, &rset, NULL, NULL, &tv);
    } while (rc < 0 && errno == EINTR);

    if (rc == 0) {
        if (JK_IS_DEBUG_LEVEL(l)) {
            jk_log(l, JK_LOG_DEBUG,
                   "timeout during select on socket %d [%s] (timeout=%d)",
                   sd, jk_dump_sinfo(sd, buf, sizeof(buf)), timeout);
        }
        /* Timeout. Set the errno to timeout */
#if defined(WIN32) || (defined(NETWARE) && defined(__NOVELL_LIBC__))
        errno = WSAETIMEDOUT - WSABASEERR;
#else
        errno = ETIMEDOUT;
#endif
        JK_TRACE_EXIT(l);
        return JK_FALSE;
    }
    else if (rc < 0) {
        save_errno = errno;
        if (JK_IS_DEBUG_LEVEL(l)) {
            jk_log(l, JK_LOG_DEBUG,
                   "error during select on socket %d [%s] (errno=%d)",
                   sd, jk_dump_sinfo(sd, buf, sizeof(buf)), errno);
        }
        errno = save_errno;
        JK_TRACE_EXIT(l);
        return JK_FALSE;
    }
    errno = 0;
    JK_TRACE_EXIT(l);
    return JK_TRUE;
}
bool ExtensionAgentResponse::writeContent(const char * content, size_t length) {
	jk_log(logger, JK_LOG_TRACE, "CONTENT [%d]\r\n%s\r\n", length, content);

	DWORD size = length;
	if (lpEcb->WriteClient(lpEcb->ConnID, (LPVOID) content, &size, HSE_IO_SYNC)) {
		jk_log(logger, JK_LOG_TRACE, "WriteClient ... OK");
		return true;
	}

	DWORD dwError;
	dwError = GetLastError();
	jk_log(logger, JK_LOG_ERROR, "WriteClient function failed = %d (%x)", dwError, dwError);
	return false;
}
bool SSOAgentRequest::parseQueryString(string qryStr) {
	vector<string> vParams;
	StringUtil::tokenize(qryStr, vParams, "&");

	vector<string>::iterator i;
	for (i = vParams.begin() ; i != vParams.end() ; i++) {
		string p = *i;
		string name, value;

		size_t pos = p.find("=");
		if (pos != string::npos) {
			// There is a '=', split the string
			name.assign(p.substr(0, pos));
			value.assign(p.substr(pos + 1));

		} else {
			// There is no '=', the param has no value
			name.assign(p);
			value.assign(SSOAgentRequest::EMPTY_PARAM);
		}
		jk_log(logger, JK_LOG_TRACE, "Received param %s:%s", name.c_str(), value.c_str());
		params[name] = value;
		
	}

	return true;
}
/**
 * This strategy returns false if the accessed URL matches any of the configured URL patterns.
 * The patterns are regular expressions.
 */
bool UrlBasedAutomaticLoginStrategy::isAutomaticLoginRequired(SSOAgentRequest *req, SSOAgentResponse *res) {
	bool autoLoginRequired = true;
	string requestUri = req->getPath();
	vector<string>::const_iterator urlPattern;
	for(urlPattern = urlPatterns.begin() ; urlPattern != urlPatterns.end() ; urlPattern++) {
		bool matched = ssoAgent->match(requestUri, *urlPattern);
		jk_log(ssoAgent->logger, JK_LOG_TRACE, "Check requested URI [%s] againt ignored pattern [%s] : %d" , requestUri.c_str(), (*urlPattern).c_str(), matched);

		if (matched) {
			jk_log(ssoAgent->logger, JK_LOG_DEBUG, "Autologin is not required! Ignored url pattern: %s", requestUri.c_str());
			autoLoginRequired = false;
			break;
		}
	}

	return autoLoginRequired;
}
/**
 * Return paramter value for the given name.  If returned string is empty, it means that the parameter was not present.
 * If the returned string is SSOAgentRequest::EMPTY_PARAM, it means that the parameter is present, without a value.
 */
string SSOAgentRequest::getParameter(string pName) {

	if (params.empty()) {

		string qryStr = this->getQueryString();
		if (!qryStr.empty()) {
			// Read and parse query string into parameters.
			parseQueryString(qryStr);
			
		} else if (!strcmp(getMethod().c_str(), "POST")) {
			
			// Read and parse request body into parametsers.
			DWORD bodySz = this->getBodySize();
			
			if (bodySz > 0) {
				LPBYTE body = this->getBody();
				jk_log(logger, JK_LOG_DEBUG, "POST Request has a body, type=[%s] size=%d", getContentType().c_str(), bodySz);
				parsePostData(body, bodySz, this->getContentType());
			} else {
				jk_log(logger, JK_LOG_DEBUG, "POST Request has no body");
			}
			
		} else {
			jk_log(logger, JK_LOG_TRACE, "GET Request has no parameters, method [%s]", getMethod().c_str());
		}

		// Just for debugging purposes
		map<string, string>::iterator i;
		for (i = params.begin() ; i != params.end() ; i++) {
			pair <string, string> p = *i;
			jk_log(logger, JK_LOG_DEBUG, "Populating request with param %s=[%s]", p.first.c_str(), p.second.c_str());
		}
	} 

	map<string, string>::const_iterator params_it;
	params_it = params.find(pName);

	// Did we find the parameter ?!
	if (params_it == params.end()) {
		return SSOAgentRequest::EMPTY_STR;
	} else {
		return params_it->second;
	}
}
예제 #14
0
int uri_worker_map_update(jk_uri_worker_map_t *uw_map,
                          int force, jk_logger_t *l)
{
    int rc = JK_TRUE;
    time_t now = time(NULL);

    if (force || (uw_map->reload > 0 && difftime(now, uw_map->checked) >
                  uw_map->reload)) {
        struct stat statbuf;
        uw_map->checked = now;
        if ((rc = jk_stat(uw_map->fname, &statbuf)) == -1) {
            jk_log(l, JK_LOG_ERROR,
                   "Unable to stat the %s (errno=%d)",
                   uw_map->fname, errno);
            return JK_FALSE;
        }
        if (statbuf.st_mtime == uw_map->modified) {
            if (JK_IS_DEBUG_LEVEL(l))
                jk_log(l, JK_LOG_DEBUG,
                       "File %s is not modified",
                       uw_map->fname);
            return JK_TRUE;
        }
        JK_ENTER_CS(&uw_map->cs);
        /* Check if some other thread updated status */
        if (statbuf.st_mtime == uw_map->modified) {
            JK_LEAVE_CS(&uw_map->cs);
            if (JK_IS_DEBUG_LEVEL(l))
                jk_log(l, JK_LOG_DEBUG,
                       "File %s  is not modified",
                       uw_map->fname);
            return JK_TRUE;
        }
        rc = uri_worker_map_load(uw_map, l);
        uri_worker_map_ext(uw_map, l);
        uri_worker_map_switch(uw_map, l);
        JK_LEAVE_CS(&uw_map->cs);
        jk_log(l, JK_LOG_INFO,
               "Reloaded urimaps from %s", uw_map->fname);
    }
    return JK_TRUE;
}
예제 #15
0
bool FilterAgentResponse::flushHeaders() {

	if (committed) {
		jk_log(this->logger, JK_LOG_ERROR, "Response already committed!");
		return false;
	}
	committed = true;

	string plainHeaders = "";
	list<pair<string, string>>::iterator h;
	for (h = headers.begin() ; h != headers.end() ; h ++) {
		pair<string, string> p = *h;
		
		plainHeaders.append(p.first);
		plainHeaders.append(": ");
		plainHeaders.append(p.second);
		plainHeaders.append("\r\n");
	}
	if (plainHeaders.empty()) {
		jk_log(logger, JK_LOG_DEBUG, "No HTTP headers in response");
	} else {
		jk_log(logger, JK_LOG_TRACE, "HTTP headers \r\n%s", plainHeaders.c_str());
	}

	// plainHeaders.append("\r\n");
	size_t length = plainHeaders.length() + 1;
	char * cHeaders = (char*)malloc(length);

	StringCbCopy(cHeaders, length, plainHeaders.c_str());

	if (!this->pfc->AddResponseHeaders(this->pfc, cHeaders, 0)) {
		DWORD dwError;
		dwError = GetLastError();
		jk_log(logger, JK_LOG_ERROR, "AddResponseHeaders[%s] failed = %d (%x)", plainHeaders.c_str(), dwError, dwError);
		return false;
	}

	free (cHeaders);

	return true;
	
}
bool SSOAgentRequest::parsePostData(LPBYTE body, DWORD bodySize, string contentType) {
	jk_log(logger, JK_LOG_TRACE, "Parsing [%d] bytes of type %s as parameters", bodySize, contentType.c_str());
	char * b = (char*) body;

	string sBody;
	
	sBody.assign(b, bodySize);
	jk_log(logger, JK_LOG_TRACE, "Body type[%s]\n%s", contentType.c_str(), sBody.c_str());
	if (strcmp(contentType.c_str(), "application/x-www-form-urlencoded") == 0) {
		return parseQueryString(sBody);

	} else if (contentType.find("multipart/form-data;") == 0) {
		return parseMimeString(contentType, sBody);

	} else {
		jk_log(logger, JK_LOG_ERROR, "POST Data content type unknown : [%s]", contentType.c_str());
		return false;
	}

}
예제 #17
0
int uri_worker_map_alloc(jk_uri_worker_map_t **uw_map_p,
                         jk_map_t *init_data, jk_logger_t *l)
{
    int i;

    JK_TRACE_ENTER(l);

    if (uw_map_p) {
        int rc;
        jk_uri_worker_map_t *uw_map;
        *uw_map_p = (jk_uri_worker_map_t *)calloc(1, sizeof(jk_uri_worker_map_t));
        uw_map = *uw_map_p;

        JK_INIT_CS(&(uw_map->cs), rc);
        if (rc == JK_FALSE) {
            jk_log(l, JK_LOG_ERROR,
                   "creating thread lock (errno=%d)",
                   errno);
            JK_TRACE_EXIT(l);
            return JK_FALSE;
        }

        jk_open_pool(&(uw_map->p),
                     uw_map->buf, sizeof(jk_pool_atom_t) * BIG_POOL_SIZE);
        for (i = 0; i <= 1; i++) {
            jk_open_pool(&(uw_map->p_dyn[i]),
                         uw_map->buf_dyn[i], sizeof(jk_pool_atom_t) * BIG_POOL_SIZE);
            uw_map->size[i] = 0;
            uw_map->nosize[i] = 0;
            uw_map->capacity[i] = 0;
            uw_map->maps[i] = NULL;
        }
        uw_map->id = 0;
        uw_map->index = 0;
        uw_map->fname = NULL;
        uw_map->reject_unsafe = 0;
        uw_map->collapse_slashes = JK_COLLAPSE_DEFAULT;
        uw_map->reload = JK_URIMAP_DEF_RELOAD;
        uw_map->modified = 0;
        uw_map->checked = 0;

        if (init_data)
            rc = uri_worker_map_open(uw_map, init_data, l);
        if (rc == JK_TRUE)
            uw_map->id = ++map_id_counter;
        JK_TRACE_EXIT(l);
        return rc;
    }

    JK_LOG_NULL_PARAMS(l);
    JK_TRACE_EXIT(l);

    return JK_FALSE;
}
예제 #18
0
BOOL WINAPI TerminateFilter (DWORD dwFlags) 
{
	/* Called When Filter is Terminated */
	if (ssoAgent->isStarted()) {
		jk_log(ssoAgent->logger, JK_LOG_DEBUG, "JOSSO Isapi Filter termination");
	}
	

	return TRUE;

}  /* TerminateFilter */
예제 #19
0
// TODO : This will not only start the response but also send all headers, without content!
bool FilterAgentResponse::startResponse(int status, string reason, list<pair<string, string>> headers) {

	if (committed) {
		jk_log(this->logger, JK_LOG_ERROR, "Response already committed!");
		return false;
	}
	committed = true;

	char statusLine[MAX_HEADER_SIZE];
	statusLine[0] = '\0';

	StringCbPrintf(statusLine, MAX_HEADER_SIZE, "%d %s", status, reason.c_str());

	string plainHeaders = "";
	list<pair<string, string>>::iterator h;
	for (h = headers.begin() ; h != headers.end() ; h ++) {
		pair<string, string> p = *h;
		
		plainHeaders.append(p.first);
		plainHeaders.append(": ");
		plainHeaders.append(p.second);
		plainHeaders.append("\r\n");
	}
	if (plainHeaders.empty()) {
		jk_log(logger, JK_LOG_WARNING, "No HTTP headers in response");
	} else {
		jk_log(logger, JK_LOG_TRACE, "HTTP headers \r\n%s", plainHeaders.c_str());
	}

	plainHeaders.append("\r\n");
	const char * cHeaders = plainHeaders.c_str();

	if(!pfc->ServerSupportFunction (pfc, SF_REQ_SEND_RESPONSE_HEADER, (PVOID) statusLine, (DWORD) cHeaders, 0)) {
		DWORD dwError;
		dwError = GetLastError();
		jk_log(logger, JK_LOG_ERROR, "ServerSupportFunction[SF_REQ_SEND_RESPONSE_HEADER] failed = %d (%x)", dwError, dwError);
		return false;
	}
		
	return true;
}
string SSOAgentRequest::getCookie(string cName) {

	jk_log(logger, JK_LOG_TRACE, "Requesting COOKIE [%s]", cName.c_str());

	if (cookies.empty()) {
		string cookieHeader = getHeader("HTTP_COOKIE");
		
		jk_log(logger, JK_LOG_TRACE, "Loading cookies from HTTP_COOKIE:\n%s", cookieHeader.c_str());
		vector <string> cs;
		StringUtil::tokenize(cookieHeader, cs, ";");

		vector<string>::iterator c;
		for (c = cs.begin() ; c != cs.end() ; c++) {
			string cookie = *c;
			// split each cookie
			size_t eqPos = cookie.find("=");
			if (eqPos >= 0) {
				string value = cookie.substr(eqPos+1);
				string name = cookie.substr(0, eqPos);
				StringUtil::trim(name);

				jk_log(logger, JK_LOG_TRACE, "Storing COOKIE [%s]=[%s]", name.c_str(), value.c_str());
				
				cookies[name] = value;
			
			}
		}
	}

	map<string, string>::const_iterator cookies_it;
	cookies_it = cookies.find(cName);

	if (cookies_it == cookies.end()) {
		jk_log(logger, JK_LOG_TRACE, "Requested COOKIE %s=[<EMPTY>]", cName.c_str());
		return SSOAgentRequest::EMPTY_STR;
	} else {
		jk_log(logger, JK_LOG_TRACE, "Requested COOKIE %s=[%s]", cName.c_str(), cookies_it->second.c_str());
		return cookies_it->second;
	}

}
예제 #21
0
/* Dump the map contents - only call if debug log is active. */
static void uri_worker_map_dump(jk_uri_worker_map_t *uw_map,
                                const char *reason, jk_logger_t *l)
{
    JK_TRACE_ENTER(l);
    if (uw_map) {
        int i, off;
        if (JK_IS_DEBUG_LEVEL(l)) {
            jk_log(l, JK_LOG_DEBUG, "uri map dump %s: id=%d, index=%d file='%s' reject_unsafe=%d "
                  "collapse_slashes=%d reload=%d modified=%d checked=%d",
                   reason, uw_map->id, uw_map->index, STRNULL_FOR_NULL(uw_map->fname),
                   uw_map->reject_unsafe, uw_map->collapse_slashes,
                   uw_map->reload, uw_map->modified, uw_map->checked);
        }
        for (i = 0; i <= 1; i++) {
            jk_log(l, JK_LOG_DEBUG, "generation %d: size=%d nosize=%d capacity=%d",
                   i, uw_map->size[i], uw_map->nosize[i], uw_map->capacity[i], uw_map->maps[i]);
        }

        off = uw_map->index;
        for (i = 0; i <= 1; i++) {
            char buf[32];
            int k;
            unsigned int j;
            k = (i + off) % 2;
            for (j = 0; j < uw_map->size[k]; j++) {
                uri_worker_record_t *uwr = uw_map->maps[k][j];
                if (uwr && JK_IS_DEBUG_LEVEL(l)) {
                    jk_log(l, JK_LOG_DEBUG, "%s (%d) map #%d: uri=%s worker=%s context=%s "
                           "source=%s type=%s len=%d",
                           i ? "NEXT" : "THIS", i, j,
                           STRNULL_FOR_NULL(uwr->uri), STRNULL_FOR_NULL(uwr->worker_name),
                           STRNULL_FOR_NULL(uwr->context), STRNULL_FOR_NULL(uri_worker_map_get_source(uwr,l)),
                           STRNULL_FOR_NULL(uri_worker_map_get_match(uwr,buf,l)), uwr->context_len);
                }
            }
        }
    }
    JK_TRACE_EXIT(l);
}
예제 #22
0
void extension_fix(jk_pool_t *p, const char *name,
                   rule_extension_t *extensions, jk_logger_t *l)
{
    jk_worker_t *jw = wc_get_worker_for_name(name, l);
    if(!jw) {
        jk_log(l, JK_LOG_ERROR,
               "Could not find worker with name '%s' in uri map post processing.",
               name);
        return;
    }
    if (!extension_fix_activation(p, name, jw, extensions, l))
        return;
    if (extensions->fail_on_status_str) {
        extension_fix_fail_on_status(p, name, extensions, l);
    }
    extension_fix_session(p, name, jw, extensions, l);
}
예제 #23
0
void uri_worker_map_switch(jk_uri_worker_map_t *uw_map, jk_logger_t *l)
{
    int new_index;

    JK_TRACE_ENTER(l);

    if (uw_map) {
        new_index = IND_SWITCH(uw_map->index);
        if (JK_IS_DEBUG_LEVEL(l))
            jk_log(l, JK_LOG_DEBUG,
                   "Switching uri worker map from index %d to index %d",
                   uw_map->index, new_index);
        uw_map->index = new_index;
        jk_reset_pool(&(IND_NEXT(uw_map->p_dyn)));
    }

    JK_TRACE_EXIT(l);

}
예제 #24
0
int ajp13_marshal_shutdown_into_msgb(jk_msg_buf_t *msg,
                                     jk_pool_t *p, jk_logger_t *l)
{
    JK_TRACE_ENTER(l);
    /* To be on the safe side */
    jk_b_reset(msg);

    /*
     * Just a single byte with s/d command.
     */
    if (jk_b_append_byte(msg, JK_AJP13_SHUTDOWN)) {
        jk_log(l, JK_LOG_ERROR,
               "failed appending shutdown message");
        JK_TRACE_EXIT(l);
        return JK_FALSE;
    }

    JK_TRACE_EXIT(l);
    return JK_TRUE;
}
예제 #25
0
/**
 * This will return a server variable value no longer that cbSize.
 */
string FilterAgentResponse::getServerVariable(string name, DWORD cbSize) {

	string value;

	if (name.empty() || cbSize < 1) {
		jk_log(logger, JK_LOG_ERROR, "Server variable name or value size are invalid %s %d", name.c_str(), cbSize);
		return false;
	}

	jk_log(logger, JK_LOG_TRACE, "getServerVariable(%s (size=%d), %d, ...)", name.c_str(), name.size(), cbSize);

	DWORD dwError;

	char *varValue = new char[cbSize];
	char *varName = new char[name.size() + 1];

	varValue[0] = '\0';
	varName[0] = '\0';

	StringCbCopy(varName, name.size() + 1, name.c_str());

	if (!pfc->GetServerVariable(pfc, varName, varValue, &cbSize)) {

		dwError = GetLastError();

		if (dwError == ERROR_INVALID_INDEX) { // Server variable does not exists
			jk_log(logger, JK_LOG_DEBUG, " GetServerVariable[%s] failed = %d (%x) (likely reason: server var not set yet), buffer size= %d\n", 
				varName, dwError, dwError, cbSize);
		} else if ( dwError == ERROR_INSUFFICIENT_BUFFER) {  // Should quit if too much header
			jk_log(logger, JK_LOG_ERROR, " GetServerVariable[%s] failed = %d (%x) (likely reason: variable data is too large for buffer), buffer size= %d\n", 
				varName, dwError, dwError, cbSize);
		} else {
			jk_log(logger, JK_LOG_ERROR, " GetServerVariable[%s] failed = %d (%x), buffer size= %d\n", 
				varName, dwError, dwError, cbSize);
		}
	
	}  else {

		jk_log(logger, JK_LOG_TRACE, "getServerVariable(%s (size=%d), %d, ...) : %s", name.c_str(), name.size(), cbSize, varValue);

		// TODO : Should this be deleted by the client ?
		value.assign(varValue);
	}

	delete varName;
	delete varValue;

	return value;
}
예제 #26
0
/** Non-blocking socket connect
 * @param sd       socket to connect
 * @param addr     address to connect to
 * @param source   optional source address
 * @param timeout  connect timeout in seconds (ignored!)
 * @param l        logger
 * @return         -1: some kind of error occured
 *                 0: success
 */
static int nb_connect(jk_sock_t sd, jk_sockaddr_t *addr, jk_sockaddr_t *source,
                      int timeout, jk_logger_t *l)
{
    int rc;
    char buf[64];

    JK_TRACE_ENTER(l);

    if (source != NULL) {
        if (bind(sd, (const struct sockaddr *)&source->sa.sin, source->salen)) {
            JK_GET_SOCKET_ERRNO();
            jk_log(l, JK_LOG_ERROR,
                   "error during source bind on socket %d [%s] (errno=%d)",
                   sd, jk_dump_hinfo(source, buf, sizeof(buf)), errno);
        }
    }
    rc = connect(sd, (const struct sockaddr *)&addr->sa.sin, addr->salen);
    JK_TRACE_EXIT(l);
    return rc;
}
예제 #27
0
static int uri_worker_map_clear(jk_uri_worker_map_t *uw_map,
                                jk_logger_t *l)
{
    uri_worker_record_t *uwr = NULL;
    unsigned int i;
    unsigned int new_size = 0;
    unsigned int new_nosize = 0;

    JK_TRACE_ENTER(l);

    IND_NEXT(uw_map->maps) =
            (uri_worker_record_t **) jk_pool_alloc(&(IND_NEXT(uw_map->p_dyn)),
                                                   sizeof(uri_worker_record_t
                                                          *) * IND_THIS(uw_map->size));
    IND_NEXT(uw_map->capacity) = IND_THIS(uw_map->size);
    IND_NEXT(uw_map->size) = 0;
    IND_NEXT(uw_map->nosize) = 0;
    for (i = 0; i < IND_THIS(uw_map->size); i++) {
        uwr = IND_THIS(uw_map->maps)[i];
        if (uwr->source_type == SOURCE_TYPE_URIMAP) {
            if (JK_IS_DEBUG_LEVEL(l))
                jk_log(l, JK_LOG_DEBUG,
                       "deleting map rule '%s=%s' source '%s'",
                       uwr->context, uwr->worker_name, uri_worker_map_get_source(uwr, l));
        }
        else {
            IND_NEXT(uw_map->maps)[new_size] = uwr;
            new_size++;
            if (uwr->match_type & MATCH_TYPE_NO_MATCH)
                new_nosize++;
        }
    }
    IND_NEXT(uw_map->size) = new_size;
    IND_NEXT(uw_map->nosize) = new_nosize;

    JK_TRACE_EXIT(l);
    return JK_TRUE;
}
bool SSOAgentRequest::parseMimeString(string contentType, string mimeStr) {

	try {

		// Create parser object
		mime::FormDataParser parser;

		// Set directory for temp files of something is uploaded
		parser.SetTempDirForFileUpload("C:\\TEMP");
		parser.SetContentType(contentType);

		parser.AcceptSomeData(mimeStr.c_str(), mimeStr.size());

		typedef std::map <std::string, mime::FormField *> FormFieldsMap; 
		
		FormFieldsMap fields = parser.GetFormFieldsMap();

		FormFieldsMap::iterator pos;
		for (pos = fields.begin() ; pos != fields.end() ; ++pos) {
			string name, value;

			name.assign(pos->first);

			mime::FormField *field = pos->second;
			value.assign(field->GetTextTypeContent());
			params[name] = value;


		}

		return true;
	} catch (mime::Exception e) {
		jk_log(logger, JK_LOG_ERROR, "Cannot parse content %s : %s", mimeStr.c_str(), e.GetError().c_str() );
		return false;
	}


}
예제 #29
0
/* Handle an HTTP request. Works out whether Tomcat will be interested then either
 * despatches it to Tomcat or passes it back to Domino.
 */
static unsigned int ParsedRequest(FilterContext *context, FilterParsedRequest *reqData)
{
	unsigned int errID;
	int rc;
	FilterRequest fr;
	int result = kFilterNotHandled;

	DEBUG(("\nParsedRequest starting\n"));

	rc = context->GetRequest(context, &fr, &errID);

	if (fr.URL && strlen(fr.URL))
	{
		char *uri = fr.URL;
		char *workerName, *qp, *turi;

		if (!initDone)
		{
			/* One time initialisation which is deferred so that we have the name of
			 * the server software to plug into worker_env
			 */
			int ok = JK_FALSE;
			jk_map_t *map = NULL;

			DEBUG(("Initialising worker map\n"));

			if (map_alloc(&map))
			{
				if (map_read_properties(map, workerMountFile))
					if (uri_worker_map_alloc(&uw_map, map, logger))
						ok = JK_TRUE;
				map_free(&map);
			}

			DEBUG(("Got the URI worker map\n"));

			if (ok)
			{
				ok = JK_FALSE;
				DEBUG(("About to allocate map\n"));
				if (map_alloc(&map))
				{
					DEBUG(("About to read %s\n", workerFile));
					if (map_read_properties(map, workerFile))
					{
#if defined(JK_VERSION) && JK_VERSION >= MAKEVERSION(1, 2, 0, 1)
						char server[256];

						worker_env.uri_to_worker = uw_map;
						if (context->GetServerVariable(context, "SERVER_SOFTWARE", server, sizeof(server)-1, &errID))
							worker_env.server_name = jk_pool_strdup(&cfgPool, server);
						else
							worker_env.server_name = SERVERDFLT;

						DEBUG(("Server name %s\n", worker_env.server_name));

						if (wc_open(map, &worker_env, logger))
							ok = JK_TRUE;
#else
						if (wc_open(map, logger))
							ok = JK_TRUE;
#endif
						DEBUG(("OK = %d\n", ok));
					}

					DEBUG(("Read %s, OK = %d\n", workerFile, ok));
					map_free(&map);
				}
			}

			if (!ok) return kFilterError;
			initDone = JK_TRUE;
                }

                turi = strdup(uri);
                if (qp = strchr(turi, '?'), tqp != NULL) *qp = '\0';
                workerName = map_uri_to_worker(uw_map, turi, logger);
                free(turi);

		DEBUG(("Worker for this URL is %s\n", workerName));

		if (NULL != workerName)
		{
			private_ws_t ws;
			jk_ws_service_t s;
			jk_pool_atom_t buf[SMALL_POOL_SIZE];

			if (BadURI(uri))
				return RejectBadURI(context);

			/* Go dispatch the call */

			jk_init_ws_service(&s);
			jk_open_pool(&ws.p, buf, sizeof (buf));

			ws.responseStarted	= JK_FALSE;
			ws.context			= context;
			ws.reqData			= reqData;

			ws.reqSize = context->GetRequestContents(context, &ws.reqBuffer, &errID);

			s.ws_private = &ws;
			s.pool = &ws.p;

			if (InitService(&ws, &s))
			{
				jk_worker_t *worker = wc_get_worker_for_name(workerName, logger);

				jk_log(logger, JK_LOG_DEBUG, "HttpExtensionProc %s a worker for name %s\n",
					   worker ? "got" : "could not get", workerName);

				if (worker)
				{
					jk_endpoint_t *e = NULL;

					if (worker->get_endpoint(worker, &e, logger))
					{
						int recover = JK_FALSE;

						if (e->service(e, &s, logger, &recover))
						{
							result = kFilterHandledRequest;
							jk_log(logger, JK_LOG_DEBUG, "HttpExtensionProc service() returned OK\n");
							DEBUG(("HttpExtensionProc service() returned OK\n"));
						}
						else
						{
							result = kFilterError;
							jk_log(logger, JK_LOG_ERROR, "HttpExtensionProc error, service() failed\n");
							DEBUG(("HttpExtensionProc error, service() failed\n"));
						}
						e->done(&e, logger);
					}
				}
				else
				{
					jk_log(logger, JK_LOG_ERROR,
						   "HttpExtensionProc error, could not get a worker for name %s\n",
						   workerName);
				}
			}

			jk_close_pool(&ws.p);
		}
	}

	return result;
}
예제 #30
0
/* Start the response by sending any headers. Invoked by Tomcat. I don't
 * particularly like the fact that this always allocates memory, but
 * perhaps jk_pool_alloc() is efficient.
 */
static int JK_METHOD StartResponse(jk_ws_service_t *s, int status, const char *reason,
									const char *const *hdrNames,
									const char *const *hdrValues, unsigned hdrCount)
{
	DEBUG(("StartResponse()\n"));
	jk_log(logger, JK_LOG_DEBUG, "Into jk_ws_service_t::StartResponse\n");

	if (status < 100 || status > 1000)
	{
		jk_log(logger, JK_LOG_ERROR, "jk_ws_service_t::StartResponse, invalid status %d\n", status);
		return JK_FALSE;
	}

	if (s && s->ws_private)
	{
		private_ws_t *p = s->ws_private;

		if (!p->responseStarted)
		{
			char *hdrBuf;
			FilterResponseHeaders frh;
			int rc, errID;

			p->responseStarted = JK_TRUE;

			if (NULL == reason)
				reason = "";

			/* Build a single string containing all the headers
			 * because that's what Domino needs.
			 */
			if (hdrCount > 0)
			{
				unsigned i;
				unsigned hdrLen;
				char *bufp;

				for (i = 0, hdrLen = 3; i < hdrCount; i++)
					hdrLen += strlen(hdrNames[i]) + strlen(hdrValues[i]) + 4;

				hdrBuf = jk_pool_alloc(&p->p, hdrLen);
				bufp = hdrBuf;

				for (i = 0; i < hdrCount; i++)
				{
					Append(&bufp, hdrNames[i]);
					Append(&bufp, ": ");
					Append(&bufp, hdrValues[i]);
					Append(&bufp, crlf);
				}

				Append(&bufp, crlf);
			}
			else
			{
				hdrBuf = crlf;
			}

			frh.responseCode = status;
			frh.reasonText = (char *) reason;
			frh.headerText = hdrBuf;

			DEBUG(("%d %s\n%s", status, reason, hdrBuf));

			/* Send the headers */
			rc = p->context->ServerSupport(p->context, kWriteResponseHeaders, &frh, NULL, 0, &errID);

			/*
			if (rc)
			{
				jk_log(logger, JK_LOG_ERROR,
					   "jk_ws_service_t::StartResponse, ServerSupportFunction failed\n");
				return JK_FALSE;
			}
			*/

		}
		return JK_TRUE;
	}

	jk_log(logger, JK_LOG_ERROR, "jk_ws_service_t::StartResponse, NULL parameters\n");

	return JK_FALSE;
}