/* * Generate a new session ID. * * Note that apr_generate_random_bytes() blocks on Linux due to reading from * /dev/random. FreeBSD /dev/random never blocks. Solaris /dev/random does * not seem to block either. To keep mod_but usable on Linux, we try to not * waste any randomness: only read as much as needed and use all bits. * On Linux, APR should be compiled to read from /dev/urandom by default. */ char * generate_session_id(request_rec *r) { apr_status_t rc; unsigned char rnd[MOD_BUT_SIDBYTES]; char *sid = apr_pcalloc(r->pool, apr_base64_encode_len(MOD_BUT_SIDBYTES) + 1); if (!sid) { ERRLOG_CRIT("FATAL: Out of memory"); return NULL; } if (APR_SUCCESS != (rc = apr_generate_random_bytes(rnd, MOD_BUT_SIDBYTES))) { ERRLOG_CRIT("FATAL: apr_generate_random_bytes returned %d", rc); return NULL; } if (0 >= apr_base64_encode_binary(sid, rnd, MOD_BUT_SIDBYTES)) { ERRLOG_CRIT("FATAL: apr_base64_encode failed"); return NULL; } ERRLOG_INFO("Session ID generated [%s]", sid); return sid; }
static char * hash_cookie(apr_pool_t *p, uint8_t *secret,int secretLen,unsigned long expires) { unsigned char hash[SHA1_DIGEST_LENGTH]; hmac_sha1(secret, secretLen, (uint8_t *) &expires, sizeof(unsigned int), hash, SHA1_DIGEST_LENGTH); int len; char *encoded = apr_palloc(p,(SHA1_DIGEST_LENGTH*2)+3); len = apr_base64_encode_binary(encoded,hash,SHA1_DIGEST_LENGTH); return encoded; }
static char *hmac_sha1(apr_pool_t *p, char *data, char *key) { apr_sha1_ctx_t context; unsigned char digest[APR_SHA1_DIGESTSIZE]; unsigned char k_ipad[65], k_opad[65]; unsigned char kt[APR_SHA1_DIGESTSIZE]; unsigned char *k = (unsigned char *)key; int key_len, i; char *out; int l, outlen; key_len = strlen(key); if(key_len > BLOCK_SIZE) { k = kt; key_len = APR_SHA1_DIGESTSIZE; } memset((void *)k_ipad, 0, sizeof(k_ipad)); memset((void *)k_opad, 0, sizeof(k_opad)); memmove(k_ipad, k, key_len); memmove(k_opad, k, key_len); for (i = 0; i < BLOCK_SIZE; i++) { k_ipad[i] ^= 0x36; k_opad[i] ^= 0x5c; } apr_sha1_init(&context); apr_sha1_update_binary(&context, k_ipad, 64); apr_sha1_update_binary(&context, (const unsigned char *)data, strlen(data)); apr_sha1_final(digest, &context); apr_sha1_init(&context); apr_sha1_update_binary(&context, k_opad, 64); apr_sha1_update_binary(&context, digest, sizeof(digest)); apr_sha1_final(digest, &context); outlen = apr_base64_encode_len(sizeof(digest)); out = apr_palloc(p, outlen); l = apr_base64_encode_binary(out, digest, sizeof(digest)); out[l - 2] = '\0'; return out; }
// static std::string LLBase64::encode(const U8* input, size_t input_size) { std::string output; if (input && input_size > 0) { // Yes, it returns int. int b64_buffer_length = apr_base64_encode_len(input_size); char* b64_buffer = new char[b64_buffer_length]; // This is faster than apr_base64_encode() if you know // you're not on an EBCDIC machine. Also, the output is // null terminated, even though the documentation doesn't // specify. See apr_base64.c for details. JC b64_buffer_length = apr_base64_encode_binary( b64_buffer, input, input_size); output.assign(b64_buffer); delete[] b64_buffer; } return output; }
void LLFilterSD2XMLRPC::streamOut(std::ostream& ostr, const LLSD& sd) { ostr << "<value>"; switch(sd.type()) { case LLSD::TypeMap: { #if LL_SPEW_STREAM_OUT_DEBUGGING llinfos << "streamOut(map) BEGIN" << llendl; #endif ostr << "<struct>"; if(ostr.fail()) { llinfos << "STREAM FAILURE writing struct" << llendl; } LLSD::map_const_iterator it = sd.beginMap(); LLSD::map_const_iterator end = sd.endMap(); for(; it != end; ++it) { ostr << "<member><name>" << xml_escape_string((*it).first) << "</name>"; streamOut(ostr, (*it).second); if(ostr.fail()) { llinfos << "STREAM FAILURE writing '" << (*it).first << "' with sd type " << (*it).second.type() << llendl; } ostr << "</member>"; } ostr << "</struct>"; #if LL_SPEW_STREAM_OUT_DEBUGGING llinfos << "streamOut(map) END" << llendl; #endif break; } case LLSD::TypeArray: { #if LL_SPEW_STREAM_OUT_DEBUGGING llinfos << "streamOut(array) BEGIN" << llendl; #endif ostr << "<array><data>"; LLSD::array_const_iterator it = sd.beginArray(); LLSD::array_const_iterator end = sd.endArray(); for(; it != end; ++it) { streamOut(ostr, *it); if(ostr.fail()) { llinfos << "STREAM FAILURE writing array element sd type " << (*it).type() << llendl; } } #if LL_SPEW_STREAM_OUT_DEBUGGING llinfos << "streamOut(array) END" << llendl; #endif ostr << "</data></array>"; break; } case LLSD::TypeUndefined: // treat undefined as a bool with a false value. case LLSD::TypeBoolean: #if LL_SPEW_STREAM_OUT_DEBUGGING llinfos << "streamOut(bool)" << llendl; #endif ostr << "<boolean>" << (sd.asBoolean() ? "1" : "0") << "</boolean>"; break; case LLSD::TypeInteger: #if LL_SPEW_STREAM_OUT_DEBUGGING llinfos << "streamOut(int)" << llendl; #endif ostr << "<i4>" << sd.asInteger() << "</i4>"; break; case LLSD::TypeReal: #if LL_SPEW_STREAM_OUT_DEBUGGING llinfos << "streamOut(real)" << llendl; #endif ostr << "<double>" << sd.asReal() << "</double>"; break; case LLSD::TypeString: #if LL_SPEW_STREAM_OUT_DEBUGGING llinfos << "streamOut(string)" << llendl; #endif ostr << "<string>" << xml_escape_string(sd.asString()) << "</string>"; break; case LLSD::TypeUUID: #if LL_SPEW_STREAM_OUT_DEBUGGING llinfos << "streamOut(uuid)" << llendl; #endif // serialize it as a string ostr << "<string>" << sd.asString() << "</string>"; break; case LLSD::TypeURI: { #if LL_SPEW_STREAM_OUT_DEBUGGING llinfos << "streamOut(uri)" << llendl; #endif // serialize it as a string ostr << "<string>" << xml_escape_string(sd.asString()) << "</string>"; break; } case LLSD::TypeBinary: { #if LL_SPEW_STREAM_OUT_DEBUGGING llinfos << "streamOut(binary)" << llendl; #endif // this is pretty inefficient, but we'll deal with that // problem when it becomes one. ostr << "<base64>"; LLSD::Binary buffer = sd.asBinary(); if(!buffer.empty()) { // *TODO: convert to LLBase64 int b64_buffer_length = apr_base64_encode_len(buffer.size()); char* b64_buffer = new char[b64_buffer_length]; b64_buffer_length = apr_base64_encode_binary( b64_buffer, &buffer[0], buffer.size()); ostr.write(b64_buffer, b64_buffer_length - 1); delete[] b64_buffer; } ostr << "</base64>"; break; } case LLSD::TypeDate: #if LL_SPEW_STREAM_OUT_DEBUGGING llinfos << "streamOut(date)" << llendl; #endif // no need to escape this since it will be alpha-numeric. ostr << "<dateTime.iso8601>" << sd.asString() << "</dateTime.iso8601>"; break; default: // unhandled type llwarns << "Unhandled structured data type: " << sd.type() << llendl; break; } ostr << "</value>"; }
S32 LLSDXMLFormatter::format_impl(const LLSD& data, std::ostream& ostr, U32 options, U32 level) const { S32 format_count = 1; std::string pre; std::string post; if (options & LLSDFormatter::OPTIONS_PRETTY) { for (U32 i = 0; i < level; i++) { pre += " "; } post = "\n"; } switch(data.type()) { case LLSD::TypeMap: if (0 == data.size()) { ostr << pre << "<map />" << post; } else { ostr << pre << "<map>" << post; LLSD::map_const_iterator iter = data.beginMap(); LLSD::map_const_iterator end = data.endMap(); for (; iter != end; ++iter) { ostr << pre << "<key>" << escapeString((*iter).first) << "</key>" << post; format_count += format_impl((*iter).second, ostr, options, level + 1); } ostr << pre << "</map>" << post; } break; case LLSD::TypeArray: if (0 == data.size()) { ostr << pre << "<array />" << post; } else { ostr << pre << "<array>" << post; LLSD::array_const_iterator iter = data.beginArray(); LLSD::array_const_iterator end = data.endArray(); for(; iter != end; ++iter) { format_count += format_impl(*iter, ostr, options, level + 1); } ostr << pre << "</array>" << post; } break; case LLSD::TypeUndefined: ostr << pre << "<undef />" << post; break; case LLSD::TypeBoolean: ostr << pre << "<boolean>"; if (mBoolAlpha || (ostr.flags() & std::ios::boolalpha)) { ostr << (data.asBoolean() ? "true" : "false"); } else { ostr << (data.asBoolean() ? 1 : 0); } ostr << "</boolean>" << post; break; case LLSD::TypeInteger: ostr << pre << "<integer>" << data.asInteger() << "</integer>" << post; break; case LLSD::TypeReal: ostr << pre << "<real>"; if (mRealFormat.empty()) { ostr << data.asReal(); } else { formatReal(data.asReal(), ostr); } ostr << "</real>" << post; break; case LLSD::TypeUUID: if (data.asUUID().isNull()) { ostr << pre << "<uuid />" << post; } else { ostr << pre << "<uuid>" << data.asUUID() << "</uuid>" << post; } break; case LLSD::TypeString: if (data.asString().empty()) ostr << pre << "<string />" << post; else ostr << pre << "<string>" << escapeString(data.asString()) <<"</string>" << post; break; case LLSD::TypeDate: ostr << pre << "<date>" << data.asDate() << "</date>" << post; break; case LLSD::TypeURI: ostr << pre << "<uri>" << escapeString(data.asString()) << "</uri>" << post; break; case LLSD::TypeBinary: { LLSD::Binary buffer = data.asBinary(); if (buffer.empty()) { ostr << pre << "<binary />" << post; } else { // *FIX: memory inefficient. // *TODO: convert to use LLBase64 ostr << pre << "<binary encoding=\"base64\">"; int b64_buffer_length = apr_base64_encode_len(buffer.size()); char* b64_buffer = new char[b64_buffer_length]; b64_buffer_length = apr_base64_encode_binary(b64_buffer, &buffer[0], buffer.size()); ostr.write(b64_buffer, b64_buffer_length - 1); delete[] b64_buffer; ostr << "</binary>" << post; } break; } default: // *NOTE: This should never happen. ostr << pre << "<undef />" << post; break; } return format_count; }