📄 helper.cxx
字号:
{ return; } nonceCount++; { DataStream s(nonceCountString); s << std::setw(8) << std::setfill('0') << std::hex << nonceCount; } DebugLog(<< "nonceCount is now: [" << nonceCountString << "]");}Auth Helper::makeChallengeResponseAuth(SipMessage& request, const Data& username, const Data& password, const Auth& challenge, const Data& cnonce, unsigned int& nonceCount, Data& nonceCountString){ Auth auth; auth.scheme() = "Digest"; auth.param(p_username) = username; assert(challenge.exists(p_realm)); auth.param(p_realm) = challenge.param(p_realm); assert(challenge.exists(p_nonce)); auth.param(p_nonce) = challenge.param(p_nonce); Data digestUri; { DataStream s(digestUri); //s << request.header(h_RequestLine).uri().host(); // wrong s << request.header(h_RequestLine).uri(); // right } auth.param(p_uri) = digestUri; Data authQop = qopOption(challenge); if (!authQop.empty()) { updateNonceCount(nonceCount, nonceCountString); auth.param(p_response) = Helper::makeResponseMD5(username, password, challenge.param(p_realm), getMethodName(request.header(h_RequestLine).getMethod()), digestUri, challenge.param(p_nonce), authQop, cnonce, nonceCountString, request.getContents()); auth.param(p_cnonce) = cnonce; auth.param(p_nc) = nonceCountString; auth.param(p_qop) = authQop; } else { assert(challenge.exists(p_realm)); auth.param(p_response) = Helper::makeResponseMD5(username, password, challenge.param(p_realm), getMethodName(request.header(h_RequestLine).getMethod()), digestUri, challenge.param(p_nonce)); } if (challenge.exists(p_algorithm)) { auth.param(p_algorithm) = challenge.param(p_algorithm); } else { auth.param(p_algorithm) = "MD5"; } if (challenge.exists(p_opaque)) { auth.param(p_opaque) = challenge.param(p_opaque); } return auth;}DataHelper::qopOption(const Auth& challenge){ // priority-order list of preferred qop tokens static Data preferredTokens[] = { Symbols::authInt, Symbols::auth }; static size_t pTokenSize=sizeof(preferredTokens)/sizeof(*preferredTokens); bool found = false; size_t index = pTokenSize; if (challenge.exists(p_qopOptions) && !challenge.param(p_qopOptions).empty()) { ParseBuffer pb(challenge.param(p_qopOptions).data(), challenge.param(p_qopOptions).size()); do { const char* anchor = pb.skipWhitespace(); pb.skipToChar(Symbols::COMMA[0]); Data q; pb.data(q, anchor); if (!pb.eof()) pb.skipChar(); for (size_t i=0; i < pTokenSize; i++) { if (q == preferredTokens[i]) { // found a preferred token; is it higher priority? if (i < index) { found = true; index = i; } } } } while(!pb.eof()); } if (found) return preferredTokens[index]; return Data::Empty; } Auth Helper::makeChallengeResponseAuthWithA1(const SipMessage& request, const Data& username, const Data& a1, const Auth& challenge, const Data& cnonce, unsigned int& nonceCount, Data& nonceCountString){ Auth auth; auth.scheme() = "Digest"; auth.param(p_username) = username; assert(challenge.exists(p_realm)); auth.param(p_realm) = challenge.param(p_realm); assert(challenge.exists(p_nonce)); auth.param(p_nonce) = challenge.param(p_nonce); Data digestUri; { DataStream s(digestUri); //s << request.header(h_RequestLine).uri().host(); // wrong s << request.header(h_RequestLine).uri(); // right } auth.param(p_uri) = digestUri; Data authQop = qopOption(challenge); if (!authQop.empty()) { updateNonceCount(nonceCount, nonceCountString); auth.param(p_response) = Helper::makeResponseMD5WithA1(a1, getMethodName(request.header(h_RequestLine).getMethod()), digestUri, challenge.param(p_nonce), authQop, cnonce, nonceCountString, request.getContents()); auth.param(p_cnonce) = cnonce; auth.param(p_nc) = nonceCountString; auth.param(p_qop) = authQop; } else { assert(challenge.exists(p_realm)); auth.param(p_response) = Helper::makeResponseMD5WithA1(a1, getMethodName(request.header(h_RequestLine).getMethod()), digestUri, challenge.param(p_nonce)); } if (challenge.exists(p_algorithm)) { auth.param(p_algorithm) = challenge.param(p_algorithm); } else { auth.param(p_algorithm) = "MD5"; } if (challenge.exists(p_opaque)) { auth.param(p_opaque) = challenge.param(p_opaque); } return auth;} //.dcm. all the auth stuff should be yanked out of helper and//architected for algorithm independancebool Helper::algorithmAndQopSupported(const Auth& challenge){ if ( !(challenge.exists(p_nonce) && challenge.exists(p_realm))) { return false; } return (!challenge.exists(p_algorithm) || isEqualNoCase(challenge.param(p_algorithm), "MD5") && (!challenge.exists(p_qop) || isEqualNoCase(challenge.param(p_qop), Symbols::auth) || isEqualNoCase(challenge.param(p_qop), Symbols::authInt)));}SipMessage& Helper::addAuthorization(SipMessage& request, const SipMessage& challenge, const Data& username, const Data& password, const Data& cnonce, unsigned int& nonceCount){ Data nonceCountString = Data::Empty; assert(challenge.isResponse()); assert(challenge.header(h_StatusLine).responseCode() == 401 || challenge.header(h_StatusLine).responseCode() == 407); if (challenge.exists(h_ProxyAuthenticates)) { const ParserContainer<Auth>& auths = challenge.header(h_ProxyAuthenticates); for (ParserContainer<Auth>::const_iterator i = auths.begin(); i != auths.end(); i++) { request.header(h_ProxyAuthorizations).push_back(makeChallengeResponseAuth(request, username, password, *i, cnonce, nonceCount, nonceCountString)); } } if (challenge.exists(h_WWWAuthenticates)) { const ParserContainer<Auth>& auths = challenge.header(h_WWWAuthenticates); for (ParserContainer<Auth>::const_iterator i = auths.begin(); i != auths.end(); i++) { request.header(h_Authorizations).push_back(makeChallengeResponseAuth(request, username, password, *i, cnonce, nonceCount, nonceCountString)); } } return request;} UriHelper::makeUri(const Data& aor, const Data& scheme){ assert(!aor.prefix("sip:")); assert(!aor.prefix("sips:")); Data tmp(aor.size() + scheme.size() + 1, Data::Preallocate); tmp += scheme; tmp += Symbols::COLON; tmp += aor; Uri uri(tmp); return uri;}voidHelper::processStrictRoute(SipMessage& request){ if (request.exists(h_Routes) && !request.header(h_Routes).empty() && !request.header(h_Routes).front().uri().exists(p_lr)) { // The next hop is a strict router. Move the next hop into the // Request-URI and move the ultimate destination to the end of the // route list. Force the message target to be the next hop router. request.header(h_Routes).push_back(NameAddr(request.header(h_RequestLine).uri())); request.header(h_RequestLine).uri() = request.header(h_Routes).front().uri(); request.header(h_Routes).pop_front(); // !jf! assert(!request.hasForceTarget()); request.setForceTarget(request.header(h_RequestLine).uri()); }}voidHelper::massageRoute(const SipMessage& request, NameAddr& rt){ assert(request.isRequest()); // .bwc. Let's not record-route with a tel uri or something, shall we? // If the topmost route header is malformed, we can get along without. if (!request.empty(h_Routes) && request.header(h_Routes).front().isWellFormed() && (request.header(h_Routes).front().uri().scheme() == "sip" || request.header(h_Routes).front().uri().scheme() == "sips" ) ) { rt.uri().scheme() = request.header(h_Routes).front().uri().scheme(); } else if(request.header(h_RequestLine).uri().scheme() == "sip" || request.header(h_RequestLine).uri().scheme() == "sips") { rt.uri().scheme() = request.header(h_RequestLine).uri().scheme(); } rt.uri().param(p_lr);}intHelper::getPortForReply(SipMessage& request){ assert(request.isRequest()); int port = 0; if(request.header(h_Vias).front().transport() == Symbols::TCP || request.header(h_Vias).front().transport() == Symbols::TLS) { // 18.2.2 - bullet 1 and 2 port = request.getSource().getPort(); if(port == 0) // .slg. not sure if it makes sense for sourcePort to be 0 { port = request.header(h_Vias).front().sentPort(); } } else // unreliable transport 18.2.2 bullets 3 and 4 { if (request.header(h_Vias).front().exists(p_rport)) { port = request.getSource().getPort(); } else { port = request.header(h_Vias).front().sentPort(); } } // If we haven't got a valid port yet, then use the default if (port <= 0 || port > 65535) { if(request.header(h_Vias).front().transport() == Symbols::TLS || request.header(h_Vias).front().transport() == Symbols::DTLS) { port = Symbols::DefaultSipsPort; } else { port = Symbols::DefaultSipPort; } } return port;}Uri Helper::fromAor(const Data& aor, const Data& scheme){ return makeUri(aor, scheme);}boolHelper::validateMessage(const SipMessage& message,resip::Data* reason){ if (message.empty(h_To) || message.empty(h_From) || message.empty(h_CSeq) || message.empty(h_CallId) || message.empty(h_Vias) || message.empty(h_Vias)) { InfoLog(<< "Missing mandatory header fields (To, From, CSeq, Call-Id or Via)"); DebugLog(<< message); if(reason) *reason="Missing mandatory header field"; return false; } else { try { message.header(h_CSeq).checkParsed(); } catch(ParseException&) { InfoLog(<<"Malformed CSeq header"); if(reason) *reason="Malformed CSeq header"; return false; } try { message.header(h_Vias).front().checkParsed(); } catch(ParseException& e) { InfoLog(<<"Malformed topmost Via header: " << e); if(reason) *reason="Malformed topmost Via header"; return false; } if (message.isRequest()) { try { message.header(h_RequestLine).checkParsed(); } catch(ParseException& e) { InfoLog(<< "Illegal request line " << e); if(reason) *reason="Malformed Request Line"; return false; } if(message.header(h_RequestLine).method()!=message.header(h_CSeq).method()) { InfoLog(<< "Method mismatch btw Request Line and CSeq"); if(reason) *reason="Method mismatch btw Request Line and CSeq"; return false; } } else { try { message.header(h_StatusLine).checkParsed(); } catch(ParseException& e) { InfoLog(<< "Malformed status line " << e); if(reason) *reason="Malformed status line"; return false; } } return true; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -