Пример #1
0
static const char *mag_sess_key(cmd_parms *parms, void *mconfig, const char *w)
{
    struct mag_config *cfg = (struct mag_config *)mconfig;
    struct databuf keys;
    unsigned char *val;
    apr_status_t rc;
    const char *k;
    int l;

    if (strncmp(w, "key:", 4) != 0) {
        ap_log_error(APLOG_MARK, APLOG_ERR, 0, parms->server,
                     "Invalid key format, expected prefix 'key:'");
        return NULL;
    }
    k = w + 4;

    l = apr_base64_decode_len(k);
    val = apr_palloc(parms->temp_pool, l);

    keys.length = (int)apr_base64_decode_binary(val, k);
    keys.value = (unsigned char *)val;

    if (keys.length != 32) {
        ap_log_error(APLOG_MARK, APLOG_ERR, 0, parms->server,
                     "Invalid key length, expected 32 got %d", keys.length);
        return NULL;
    }

    rc = SEAL_KEY_CREATE(cfg->pool, &cfg->mag_skey, &keys);
    if (rc != OK) {
        ap_log_error(APLOG_MARK, APLOG_ERR, 0, parms->server,
                     "Failed to import sealing key!");
    }
    return NULL;
}
Пример #2
0
// static
std::vector<U8> LLBase64::decode(std::string input)
{
	std::vector<U8> data;
	if (input.length() > 0)
	{
		// Because we're decoding binary data, we don't want the null terminator
		// figured into our array size calculations, so we reduce the reported size by 1.
		size_t data_length = static_cast<size_t>(apr_base64_decode_len(input.c_str())) - 1;
		if (data_length > 0)
		{
			data.resize(data_length);
			apr_base64_decode_binary(&data[0], input.c_str());
		}
	}
	
	return data;
}
Пример #3
0
bool LLSDNotationParser::parseBinary(std::istream& istr, LLSD& data) const
{
	// binary: b##"ff3120ab1"
	// or: b(len)"..."

	// I want to manually control those values here to make sure the
	// parser doesn't break when someone changes a constant somewhere
	// else.
	const U32 BINARY_BUFFER_SIZE = 256;
	const U32 STREAM_GET_COUNT = 255;

	// need to read the base out.
	char buf[BINARY_BUFFER_SIZE];		/* Flawfinder: ignore */
	get(istr, buf, STREAM_GET_COUNT, '"');
	char c = get(istr);
	if(c != '"') return false;
	if(0 == strncmp("b(", buf, 2))
	{
		// We probably have a valid raw binary stream. determine
		// the size, and read it.
		S32 len = strtol(buf + 2, NULL, 0);
		if(mCheckLimits && (len > mMaxBytesLeft)) return false;
		std::vector<U8> value;
		if(len)
		{
			value.resize(len);
			account(fullread(istr, (char *)&value[0], len));
		}
		c = get(istr); // strip off the trailing double-quote
		data = value;
	}
	else if(0 == strncmp("b64", buf, 3))
	{
		// *FIX: A bit inefficient, but works for now. To make the
		// format better, I would need to add a hint into the
		// serialization format that indicated how long it was.
		std::stringstream coded_stream;
		get(istr, *(coded_stream.rdbuf()), '\"');
		c = get(istr);
		std::string encoded(coded_stream.str());
		S32 len = apr_base64_decode_len(encoded.c_str());
		std::vector<U8> value;
		if(len)
		{
			value.resize(len);
			len = apr_base64_decode_binary(&value[0], encoded.c_str());
			value.resize(len);
		}
		data = value;
	}
	else if(0 == strncmp("b16", buf, 3))
	{
		// yay, base 16. We pop the next character which is either a
		// double quote or base 16 data. If it's a double quote, we're
		// done parsing. If it's not, put the data back, and read the
		// stream until the next double quote.
		char* read;	 /*Flawfinder: ignore*/
		U8 byte;
		U8 byte_buffer[BINARY_BUFFER_SIZE];
		U8* write;
		std::vector<U8> value;
		c = get(istr);
		while(c != '"')
		{
			putback(istr, c);
			read = buf;
			write = byte_buffer;
			get(istr, buf, STREAM_GET_COUNT, '"');
			c = get(istr);
			while(*read != '\0')	 /*Flawfinder: ignore*/
			{
				byte = hex_as_nybble(*read++);
				byte = byte << 4;
				byte |= hex_as_nybble(*read++);
				*write++ = byte;
			}
			// copy the data out of the byte buffer
			value.insert(value.end(), byte_buffer, write);
		}
		data = value;
	}
	else
	{
		return false;
	}
	return true;
}
void LLSDXMLParser::Impl::endElementHandler(const XML_Char* name)
{
	#ifdef XML_PARSER_PERFORMANCE_TESTS
	XML_Timer timer(&endElementTime);
	#endif // XML_PARSER_PERFORMANCE_TESTS

	--mDepth;
	if (mSkipping)
	{
		if (mDepth < mSkipThrough)
		{
			mSkipping = false;
		}
		return;
	}

	Element element = readElement(name);

	switch (element)
	{
		case ELEMENT_LLSD:
			if (mInLLSDElement)
			{
				mInLLSDElement = false;
				mGracefullStop = true;
				XML_StopParser(mParser, false);
			}
			return;

		case ELEMENT_KEY:
			mCurrentKey = mCurrentContent;
			return;

		default:
			// all rest are values, fall through
			;
	}

	if (!mInLLSDElement) { return; }

	LLSD& value = *mStack.back();
	mStack.pop_back();

	switch (element)
	{
		case ELEMENT_UNDEF:
			value.clear();
			break;

		case ELEMENT_BOOL:
			value = (mCurrentContent == "true" || mCurrentContent == "1");
			break;

		case ELEMENT_INTEGER:
		{
			S32 i;
			if (sscanf(mCurrentContent.c_str(), "%d", &i) == 1)
			{	// See if sscanf works - it's faster
				value = i;
			}
			else
			{
				value = LLSD(mCurrentContent).asInteger();
			}
			break;
		}

		case ELEMENT_REAL:
		{
			// sscanf() is sensitive to the locale and will fail decoding
			// the decimal point for locales where the decimal separator
			// is a comma... So, better not using sscanf() for this purpose.
			// See http://jira.secondlife.com/browse/EXP-700
#if 0
			F64 r;
			if (sscanf(mCurrentContent.c_str(), "%lf", &r) == 1)
			{	// See if sscanf works - it's faster
				value = r;
			}
			else
			{
				value = LLSD(mCurrentContent).asReal();
			}
#else
			value = LLSD(mCurrentContent).asReal();
#endif
			break;
		}

		case ELEMENT_STRING:
			value = mCurrentContent;
			break;

		case ELEMENT_UUID:
			value = LLSD(mCurrentContent).asUUID();
			break;

		case ELEMENT_DATE:
			value = LLSD(mCurrentContent).asDate();
			break;

		case ELEMENT_URI:
			value = LLSD(mCurrentContent).asURI();
			break;

		case ELEMENT_BINARY:
		{
			// Regex is expensive, but only fix for whitespace in base64,
			// created by python and other non-linden systems - DEV-39358
			// Fortunately we have very little binary passing now,
			// so performance impact shold be negligible. + poppy 2009-09-04
			boost::regex r;
			r.assign("\\s");
			std::string stripped = boost::regex_replace(mCurrentContent, r, "");
			S32 len = apr_base64_decode_len(stripped.c_str());
			std::vector<U8> data;
			data.resize(len);
			len = apr_base64_decode_binary(&data[0], stripped.c_str());
			data.resize(len);
			value = data;
			break;
		}

		case ELEMENT_UNKNOWN:
			value.clear();
			break;

		default:
			// other values, map and array, have already been set
			break;
	}

	mCurrentContent.clear();
}
Пример #5
0
void LLSDXMLParser::Impl::endElementHandler(const XML_Char* name)
{
	#ifdef XML_PARSER_PERFORMANCE_TESTS
	XML_Timer timer( &endElementTime );
	#endif // XML_PARSER_PERFORMANCE_TESTS

	--mDepth;
	if (mSkipping)
	{
		if (mDepth < mSkipThrough)
		{
			mSkipping = false;
		}
		return;
	}
	
	Element element = readElement(name);
	
	switch (element)
	{
		case ELEMENT_LLSD:
			if (mInLLSDElement)
			{
				mInLLSDElement = false;
				mGracefullStop = true;
				XML_StopParser(mParser, false);
			}
			return;
	
		case ELEMENT_KEY:
			mCurrentKey = mCurrentContent;
			return;
			
		default:
			// all rest are values, fall through
			;
	}
	
	if (!mInLLSDElement) { return; }

	LLSD& value = *mStack.back();
	mStack.pop_back();
	
	switch (element)
	{
		case ELEMENT_UNDEF:
			value.clear();
			break;
		
		case ELEMENT_BOOL:
			value = (mCurrentContent == "true" || mCurrentContent == "1");
			break;
		
		case ELEMENT_INTEGER:
			{
				S32 i;
				if ( sscanf(mCurrentContent.c_str(), "%d", &i ) == 1 )
				{	// See if sscanf works - it's faster
					value = i;
				}
				else
				{
					value = LLSD(mCurrentContent).asInteger();
				}
			}
			break;
		
		case ELEMENT_REAL:
			{
				F64 r;
				if ( sscanf(mCurrentContent.c_str(), "%lf", &r ) == 1 )
				{	// See if sscanf works - it's faster
					value = r;
				}
				else
				{
					value = LLSD(mCurrentContent).asReal();
				}
			}
			break;
		
		case ELEMENT_STRING:
			value = mCurrentContent;
			break;
		
		case ELEMENT_UUID:
			value = LLSD(mCurrentContent).asUUID();
			break;
		
		case ELEMENT_DATE:
			value = LLSD(mCurrentContent).asDate();
			break;
		
		case ELEMENT_URI:
			value = LLSD(mCurrentContent).asURI();
			break;
		
		case ELEMENT_BINARY:
		{
			S32 len = apr_base64_decode_len(mCurrentContent.c_str());
			std::vector<U8> data;
			data.resize(len);
			len = apr_base64_decode_binary(&data[0], mCurrentContent.c_str());
			data.resize(len);
			value = data;
			break;
		}
		
		case ELEMENT_UNKNOWN:
			value.clear();
			break;
			
		default:
			// other values, map and array, have already been set
			break;
	}

	mCurrentContent.clear();
}
Пример #6
0
void LLSDXMLParser::Impl::endElementHandler(const XML_Char* name)
{
	#ifdef XML_PARSER_PERFORMANCE_TESTS
	XML_Timer timer( &endElementTime );
	#endif // XML_PARSER_PERFORMANCE_TESTS

	--mDepth;
	if (mSkipping)
	{
		if (mDepth < mSkipThrough)
		{
			mSkipping = false;
		}
		return;
	}
	
	Element element = readElement(name);
	
	switch (element)
	{
		case ELEMENT_LLSD:
			if (mInLLSDElement)
			{
				mInLLSDElement = false;
				mGracefullStop = true;
				XML_StopParser(mParser, false);
			}
			return;
	
		case ELEMENT_KEY:
			mCurrentKey = mCurrentContent;
			return;
			
		default:
			// all rest are values, fall through
			;
	}
	
	if (!mInLLSDElement) { return; }

	LLSD& value = *mStack.back();
	mStack.pop_back();
	
	switch (element)
	{
		case ELEMENT_UNDEF:
			value.clear();
			break;
		
		case ELEMENT_BOOL:
			value = (mCurrentContent == "true" || mCurrentContent == "1");
			break;
		
		case ELEMENT_INTEGER:
			{
				S32 i;
				// sscanf okay here with different locales - ints don't change for different locale settings like floats do.
				if ( sscanf(mCurrentContent.c_str(), "%d", &i ) == 1 )
				{	// See if sscanf works - it's faster
					value = i;
				}
				else
				{
					value = LLSD(mCurrentContent).asInteger();
				}
			}
			break;
		
		case ELEMENT_REAL:
			{
				value = LLSD(mCurrentContent).asReal();
				// removed since this breaks when locale has decimal separator that isn't '.'
				// investigated changing local to something compatible each time but deemed higher
				// risk that just using LLSD.asReal() each time.
				//F64 r;
				//if ( sscanf(mCurrentContent.c_str(), "%lf", &r ) == 1 )
				//{	// See if sscanf works - it's faster
				//	value = r;
				//}
				//else
				//{
				//	value = LLSD(mCurrentContent).asReal();
				//}
			}
			break;
		
		case ELEMENT_STRING:
			value = mCurrentContent;
			break;
		
		case ELEMENT_UUID:
			value = LLSD(mCurrentContent).asUUID();
			break;
		
		case ELEMENT_DATE:
			value = LLSD(mCurrentContent).asDate();
			break;
		
		case ELEMENT_URI:
			value = LLSD(mCurrentContent).asURI();
			break;
		
		case ELEMENT_BINARY:
		{
			// Regex is expensive, but only fix for whitespace in base64,
			// created by python and other non-linden systems - DEV-39358
			// Fortunately we have very little binary passing now,
			// so performance impact shold be negligible. + poppy 2009-09-04
			boost::regex r;
			r.assign("\\s");
			std::string stripped = boost::regex_replace(mCurrentContent, r, "");
			S32 len = apr_base64_decode_len(stripped.c_str());
			std::vector<U8> data;
			data.resize(len);
			len = apr_base64_decode_binary(&data[0], stripped.c_str());
			data.resize(len);
			value = data;
			break;
		}
		
		case ELEMENT_UNKNOWN:
			value.clear();
			break;
			
		default:
			// other values, map and array, have already been set
			break;
	}

	mCurrentContent.clear();
}
static size_t CALLBACK tcp_proxy_on_message(void *plugin_private,
                                            const WebSocketServer * server,
                                            const int type,
                                            unsigned char *buffer,
                                            const size_t buffer_size)
{
    TcpProxyData *tpd = (TcpProxyData *) plugin_private;

    request_rec *r = server->request(server);

    if (tpd && tpd->tcpsocket) {
        apr_size_t len = buffer_size;
        apr_status_t rv;
        unsigned char *towrite = buffer;

        if (tpd->base64) {
            /* Unfortunately we cannot guarantee our buffer is 0 terminated, which irritatingly
             * means we have to copy it
             */
            towrite = NULL;
            unsigned char *ztbuf = calloc(1, len + 1);
            if (!ztbuf)
                goto fail;
            towrite = calloc(1, len + 1);
            if (!towrite) {
                free(ztbuf);
                goto fail;
            }
            memcpy(ztbuf, buffer, len);
            len = apr_base64_decode_binary(towrite, ztbuf);
            free(ztbuf);
            if (len <= 0) {
                free(towrite);
                towrite = NULL;
            }
          fail:
            if (!towrite) {
                APACHELOG(APLOG_DEBUG, r,
                          "tcp_proxy_on_message: apr_base64_decode_binary failed");
                tcp_proxy_shutdown_socket(tpd);
                tpd->server->close(tpd->server);
                return 0;
            }
        }

        rv = apr_socket_send(tpd->tcpsocket, towrite, &len);
        if (tpd->base64)
            free(towrite);

        if (rv != APR_SUCCESS) {
            char s[1024];
            apr_strerror(rv, s, sizeof(s));
            APACHELOG(APLOG_DEBUG, r,
                      "tcp_proxy_on_message: apr_socket_send failed, rv=%d, sent=%lu, %s",
                      rv, (unsigned long) len, s);
            tcp_proxy_shutdown_socket(tpd);
            tpd->server->close(tpd->server);
            return 0;
        }

        /*
           len = 2;
           rv = apr_socket_send(tpd->tcpsocket, "\r\n", &len);
         */
    }

    return 0;
}