END_TEST

START_TEST(isSSL_test) {
  /* stuff state into an arbitrary place in the pool */
  apr_pool_userdata_set("https", "scheme", NULL, request->pool);
  fail_unless(isSSL(request) == TRUE);
  apr_pool_userdata_set("http", "scheme", NULL, request->pool);
  fail_unless(isSSL(request) == FALSE);
}
void KConnectionSelectable::ssl_destroy()
{
#ifdef KSOCKET_SSL
	if (socket && isSSL() && selector) {
			resultSSLShutdown(0);
			return;
	}
#endif
	delete this;
}
Beispiel #3
0
void KSelectable::eventWrite(void *arg,resultEvent result,bufferEvent buffer)
{
#define MAXSENDBUF 16
	if (unlikely(buffer==NULL)) {
		result(arg,0);
		return;
	}
	WSABUF recvBuf[MAXSENDBUF];
	memset(&recvBuf,0,sizeof(recvBuf));
	int bufferCount = MAXSENDBUF;
	KClientSocket *server = static_cast<KClientSocket *>(getSocket());
	buffer(arg,recvBuf,bufferCount);
	assert(recvBuf[0].iov_len>0);
	int got = server->writev(recvBuf,bufferCount,isSSL());
	if (got>=0) {
		result(arg,got);
		return;
	}
	/*
	if (errno==EINTR) {
		continue;
	}
	*/
	if (errno==EAGAIN) {
		if (!selector->write(this,result,buffer,arg)) {
			result(arg,-1);
		}
		return;
	}
#ifdef KSOCKET_SSL
	if (isSSL()) {
		KSSLSocket *sslsocket = static_cast<KSSLSocket *>(server);
		if (sslsocket->get_ssl_error(got)==SSL_ERROR_WANT_WRITE) {
			if (!selector->write(this,result,buffer,arg)) {
				result(arg,-1);
			}
			return;
		}
	}
#endif
	result(arg,-1);
}
Beispiel #4
0
void KSelectable::asyncRead(void *arg,resultEvent result,bufferEvent buffer)
{
#ifdef KSOCKET_SSL
	if (isSSL()) {
		KSSLSocket *sslsocket = static_cast<KSSLSocket *>(getSocket());
		if (SSL_pending(sslsocket->getSSL()) > 0) {
			//ssl still have data to read
			eventRead(arg,result,buffer);
			return;
		}
	}
#endif
	if (!selector->read(this,result,buffer,arg)) {
		result(arg,-1);
	}
}
Beispiel #5
0
void KSelectable::eventRead(void *arg,resultEvent result,bufferEvent buffer)
{
	if (buffer==NULL) {
		result(arg,0);
		return;
	}
	WSABUF recvBuf[1];
	memset(&recvBuf,0,sizeof(recvBuf));
	int bufferCount = 1;
	KClientSocket *server = static_cast<KClientSocket *>(getSocket());
	buffer(arg,recvBuf,bufferCount);
	assert(recvBuf[0].iov_len>0);
	int got = server->read((char *)recvBuf[0].iov_base,recvBuf[0].iov_len);
	if (got>=0) {
		result(arg,got);
		return;
	}
	if (errno==EAGAIN) {
		if (!selector->read(this,result,buffer,arg)) {
			result(arg,-1);
		}
		return;
	}
#ifdef KSOCKET_SSL
	if (isSSL()) {
		KSSLSocket *sslsocket = static_cast<KSSLSocket *>(server);
		int err = sslsocket->get_ssl_error(got);
		if (err==SSL_ERROR_WANT_READ) {
			if (!selector->read(this,result,buffer,arg)) {
				result(arg,-1);
			}
			return;
		}
	}
#endif
	result(arg,-1);
}
int KConnectionSelectable::write(KHttpRequest *rq,LPWSABUF buf,int bufCount)
{
	
	return socket->writev(buf,bufCount,isSSL());
}
int HttpListener::handleEvents( short event )
{
    static struct conn_data conns[CONN_BATCH_SIZE];
    static struct conn_data * pEnd = &conns[CONN_BATCH_SIZE];
    struct conn_data * pCur = conns;
    int allowed;
    int iCount = 0;
    ConnLimitCtrl * pCLC = HttpGlobals::getConnLimitCtrl();
    int limitType = 1;
    allowed = pCLC->availConn();
    if ( isSSL() )
    {
        if ( allowed > pCLC->availSSLConn() )
        {
            allowed = pCLC->availSSLConn();
            limitType = 2;
        }
    }

    while( iCount < allowed )
    {
        socklen_t len = 24;
        pCur->fd = accept( getfd(), (struct sockaddr *)(pCur->achPeerAddr), &len );
        if ( pCur->fd == -1 )
        {
            resetRevent( POLLIN );
            if (( errno != EAGAIN )&&( errno != ECONNABORTED )
                &&( errno != EINTR ))
            {
                LOG_ERR(( getLogger(),
                    "HttpListener::acceptConnection(): [%s] can't accept:%s!",
                    getAddrStr(), strerror( errno ) ));
            }
            break;
        }
        //++iCount;
        //addConnection( conns, &iCount );
        
        ++pCur;
        if ( pCur == pEnd )
        {
            iCount += CONN_BATCH_SIZE;
            batchAddConn( conns, pCur, &iCount );
            pCur = conns;
        }

    }
    if ( pCur > conns )
    {
        int n = pCur - conns;
        iCount += n;
        if ( n > 1 )
            batchAddConn( conns, pCur, &iCount );
        else
            addConnection( conns, &iCount );
    }
    if ( iCount > 0 )
    {
        m_pMapVHost->incRef( iCount );
        pCLC->incConn( iCount );
    }
    if ( iCount >= allowed )
    {
        if ( limitType == 1 )
        {
            if ( D_ENABLED( DL_MORE ) )
            {
                LOG_D(( getLogger(),
                    "[%s] max connections reached, suspend accepting!",
                    getAddrStr() ));
            }
            pCLC->suspendAll();
        }
        else
        {
            if ( D_ENABLED( DL_MORE ) )
            {
                LOG_D(( getLogger(),
                    "[%s] max SSL connections reached, suspend accepting!",
                    getAddrStr() ));
            }
            pCLC->suspendSSL();
        }
    }
    if ( D_ENABLED( DL_MORE ) )
    {
        LOG_D(( getLogger(),
            "[%s] %d connections accepted!", getAddrStr(), iCount ));
    }
    return 0;
}
/* urls can't contain null pointer, caller must ensure this */
static enum phish_status phishingCheck(const struct cl_engine* engine,struct url_check* urls)
{
	struct url_check host_url;
	enum phish_status rc=CL_PHISH_NODECISION;
	int phishy=0;
	const struct phishcheck* pchk = (const struct phishcheck*) engine->phishcheck;

	if(!urls->realLink.data)
		return CL_PHISH_CLEAN;

	cli_dbgmsg("Phishcheck:Checking url %s->%s\n", urls->realLink.data,
		urls->displayLink.data);

	if(!strcmp(urls->realLink.data,urls->displayLink.data))
		return CL_PHISH_CLEAN;/* displayed and real URL are identical -> clean */

	if((rc = cleanupURLs(urls))) {
		if(isPhishing(rc))/* not allowed to decide this is phishing */
			return CL_PHISH_CLEAN;
		return rc;/* URLs identical after cleanup */
	}

	if(whitelist_check(engine,urls,0))
		return CL_PHISH_WHITELISTED;/* if url is whitelist don't perform further checks */

	if((!isURL(pchk, urls->displayLink.data) || !isRealURL(pchk, urls->realLink.data) )&&
			( (phishy&PHISHY_NUMERIC_IP && !isNumericURL(pchk, urls->displayLink.data)) ||
			  !(phishy&PHISHY_NUMERIC_IP))) {
		cli_dbgmsg("Displayed 'url' is not url:%s\n",urls->displayLink.data);
		return CL_PHISH_TEXTURL;
	}

	if(urls->flags&DOMAINLIST_REQUIRED && domainlist_match(engine,urls->realLink.data,urls->displayLink.data,NULL,0,&urls->flags))
		phishy |= DOMAIN_LISTED;
	else {
		/* although entire url is not listed, the host might be,
		 * so defer phishing decisions till we know if host is listed*/
	}

	
	url_check_init(&host_url);

	if((rc = url_get_host(pchk, urls,&host_url,DOMAIN_DISPLAY,&phishy))) {
		free_if_needed(&host_url);
		if(isPhishing(rc))
			return CL_PHISH_CLEAN;
		return rc;
	}


	if(urls->flags&DOMAINLIST_REQUIRED) {
		if(!(phishy&DOMAIN_LISTED)) {
			if(domainlist_match(engine,host_url.displayLink.data,host_url.realLink.data,&urls->pre_fixup,1,&urls->flags))
				phishy |= DOMAIN_LISTED;
			else {
			}
		}
	}

	/* link type filtering must occur after last domainlist_match */
	if(urls->link_type & LINKTYPE_IMAGE && !(urls->flags&CHECK_IMG_URL))
		return CL_PHISH_HOST_NOT_LISTED;/* its listed, but this link type is filtered */

	if(urls->flags & DOMAINLIST_REQUIRED && !(phishy & DOMAIN_LISTED) ) {
		urls->flags &= urls->always_check_flags;
		if(!urls->flags) {
				free_if_needed(&host_url);
				return CL_PHISH_HOST_NOT_LISTED;
			}
		}

	if(urls->flags&CHECK_CLOAKING) {
		/*Checks if URL is cloaked.
		Should we check if it contains another http://, https://?
		No because we might get false positives from redirect services.*/
		if(strchr(urls->realLink.data,0x1)) {
			free_if_needed(&host_url);
			return CL_PHISH_CLOAKED_NULL;
		}
		if(isEncoded(urls->displayLink.data)) {
			free_if_needed(&host_url);
			return CL_PHISH_HEX_URL;
		}
	}


	if(urls->displayLink.data[0]=='\0') {
		free_if_needed(&host_url);
		return CL_PHISH_CLEAN;
	}

	if(urls->flags&CHECK_SSL && isSSL(urls->displayLink.data) && !isSSL(urls->realLink.data)) {
		free_if_needed(&host_url);
		return CL_PHISH_SSL_SPOOF;
	}

	if(!urls->flags&CHECK_CLOAKING && urls->flags & DOMAINLIST_REQUIRED && !(phishy&DOMAIN_LISTED) ) {
		free_if_needed(&host_url);
		return CL_PHISH_HOST_NOT_LISTED;
	}

	if((rc = url_get_host(pchk, urls,&host_url,DOMAIN_REAL,&phishy)))
	{
		free_if_needed(&host_url);
		return rc;
	}

	if(urls->flags&DOMAINLIST_REQUIRED && !(phishy&DOMAIN_LISTED)) {
		free_if_needed(&host_url);
		return CL_PHISH_HOST_NOT_LISTED;
	}

	if(whitelist_check(engine,&host_url,1)) {
		free_if_needed(&host_url);
		return CL_PHISH_HOST_WHITELISTED;
	}


	if(urls->flags&HOST_SUFFICIENT) {
		if(!strcmp(urls->realLink.data,urls->displayLink.data)) {
			free_if_needed(&host_url);
			return CL_PHISH_HOST_OK;
		}


		if(urls->flags&DOMAIN_SUFFICIENT) {
			struct url_check domain_url;
			url_check_init(&domain_url);
			url_get_domain(pchk, &host_url,&domain_url);
			if(!strcmp(domain_url.realLink.data,domain_url.displayLink.data)) {
				free_if_needed(&host_url);
				free_if_needed(&domain_url);
				return CL_PHISH_DOMAIN_OK;
			}
			free_if_needed(&domain_url);
		}

		free_if_needed(&host_url);
	}/*HOST_SUFFICIENT*/
	/*we failed to find a reason why the 2 URLs are different, this is definitely phishing*/
	if(urls->flags&DOMAINLIST_REQUIRED && !(phishy&DOMAIN_LISTED))
		return CL_PHISH_HOST_NOT_LISTED;
	return phishy_map(phishy,CL_PHISH_NOMATCH);
}
Beispiel #9
0
/* urls can't contain null pointer, caller must ensure this */
static enum phish_status phishingCheck(const struct cl_engine* engine,struct url_check* urls)
{
	struct url_check host_url;
	int rc = CL_PHISH_NODECISION;
	int phishy=0;
	const struct phishcheck* pchk = (const struct phishcheck*) engine->phishcheck;

	if(!urls->realLink.data)
		return CL_PHISH_CLEAN;

	cli_dbgmsg("Phishcheck:Checking url %s->%s\n", urls->realLink.data,
		urls->displayLink.data);

	if(!isURL(urls->realLink.data, 0)) {
		cli_dbgmsg("Real 'url' is not url:%s\n",urls->realLink.data);
		return CL_PHISH_CLEAN;
	}

	if(( rc = url_hash_match(engine->domainlist_matcher, urls->realLink.data, strlen(urls->realLink.data)) )) {
	    if (rc == CL_PHISH_CLEAN) {
		cli_dbgmsg("not analyzing, not a real url: %s\n", urls->realLink.data);
		return CL_PHISH_CLEAN;
	    } else {
		cli_dbgmsg("Hash matched for: %s\n", urls->realLink.data);
		return rc;
	    }
	}

	if(!strcmp(urls->realLink.data,urls->displayLink.data))
		return CL_PHISH_CLEAN;/* displayed and real URL are identical -> clean */

	if (urls->displayLink.data[0] == '\0') {
	    return CL_PHISH_CLEAN;
	}

	if((rc = cleanupURLs(urls))) {
		/* it can only return an error, or say its clean;
		 * it is not allowed to decide it is phishing */
		return rc < 0 ? rc : CL_PHISH_CLEAN;
	}

	cli_dbgmsg("Phishcheck:URL after cleanup: %s->%s\n", urls->realLink.data,
		urls->displayLink.data);

	if((!isURL(urls->displayLink.data, 1) ) &&
			( (phishy&PHISHY_NUMERIC_IP && !isNumericURL(pchk, urls->displayLink.data)) ||
			  !(phishy&PHISHY_NUMERIC_IP))) {
		cli_dbgmsg("Displayed 'url' is not url:%s\n",urls->displayLink.data);
		return CL_PHISH_CLEAN;
	}

	if(whitelist_check(engine, urls, 0))
		return CL_PHISH_CLEAN;/* if url is whitelisted don't perform further checks */

	url_check_init(&host_url);

	if((rc = url_get_host(urls, &host_url, DOMAIN_DISPLAY, &phishy))) {
		free_if_needed(&host_url);
		return rc < 0 ? rc : CL_PHISH_CLEAN;
	}

	if (domainlist_match(engine, host_url.displayLink.data,host_url.realLink.data,&urls->pre_fixup,1)) {
		phishy |= DOMAIN_LISTED;
	} else {
		urls->flags &= urls->always_check_flags;
		/* don't return, we may need to check for ssl/cloaking */
	}

	/* link type filtering must occur after last domainlist_match */
	if(urls->link_type & LINKTYPE_IMAGE && !(urls->flags&CHECK_IMG_URL)) {
		free_if_needed(&host_url);
		return CL_PHISH_CLEAN;/* its listed, but this link type is filtered */
	}

	if(urls->flags&CHECK_CLOAKING) {
		/*Checks if URL is cloaked.
		Should we check if it contains another http://, https://?
		No because we might get false positives from redirect services.*/
		if(strchr(urls->realLink.data,0x1)) {
			free_if_needed(&host_url);
			return CL_PHISH_CLOAKED_NULL;
		}
	}

	if(urls->flags&CHECK_SSL && isSSL(urls->displayLink.data) && !isSSL(urls->realLink.data)) {
		free_if_needed(&host_url);
		return CL_PHISH_SSL_SPOOF;
	}

	if (!(phishy & DOMAIN_LISTED)) {
		free_if_needed(&host_url);
		return CL_PHISH_CLEAN;
	}

	if((rc = url_get_host(urls,&host_url,DOMAIN_REAL,&phishy)))
	{
		free_if_needed(&host_url);
		return rc < 0 ? rc : CL_PHISH_CLEAN;
	}

	if(whitelist_check(engine,&host_url,1)) {
		free_if_needed(&host_url);
		return CL_PHISH_CLEAN;
	}

	if(!strcmp(urls->realLink.data,urls->displayLink.data)) {
		free_if_needed(&host_url);
		return CL_PHISH_CLEAN;
	}

	{
		struct url_check domain_url;
		url_check_init(&domain_url);
		url_get_domain(&host_url,&domain_url);
		if(!strcmp(domain_url.realLink.data,domain_url.displayLink.data)) {
			free_if_needed(&host_url);
			free_if_needed(&domain_url);
			return CL_PHISH_CLEAN;
		}
		free_if_needed(&domain_url);
	}

	free_if_needed(&host_url);
	/*we failed to find a reason why the 2 URLs are different, this is definitely phishing*/
	return phishy_map(phishy,CL_PHISH_NOMATCH);
}