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; }
// 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; }
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(); }
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(); }
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; }