/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "challenge.h" #include "definitions.h" #include "log.h" #include "util.h" t_digest_challenge::t_digest_challenge() { stale = false; // The default algorithm is MD5. algorithm = ALG_MD5; } string t_digest_challenge::encode(void) const { string s; if (realm.size() > 0) { if (s.size() > 0) s += ','; s += "realm="; s += '"'; s += realm; s += '"'; } if (domain.size() > 0) { if (s.size() > 0) s += ','; s += "domain="; s += '"'; for (list::const_iterator i = domain.begin(); i != domain.end(); i++) { if (i != domain.begin()) s += ' '; s += i->encode(); } s += '"'; } if (nonce.size() > 0) { if (s.size() > 0) s += ','; s += "nonce="; s += '"'; s += nonce; s += '"'; } if (opaque.size() > 0) { if (s.size() > 0) s += ','; s += "opaque="; s += '"'; s += opaque; s += '"'; } // RFC 2617 3.2.1 // If the stale flag is absent it means stale=false. if (stale) { if (s.size() > 0) s += ','; s += "stale=true"; } if (algorithm.size() > 0) { if (s.size() > 0) s += ','; s += "algorithm="; s += algorithm; } if (qop_options.size() > 0) { if (s.size() > 0) s += ','; s += "qop="; s += '"'; for (list::const_iterator i = qop_options.begin(); i != qop_options.end(); i++) { if (i != qop_options.begin()) s += ','; s += *i; } s += '"'; } for (list::const_iterator i = auth_params.begin(); i != auth_params.end(); i++) { if (s.size() > 0) s += ','; s += i->encode(); } return s; } bool t_digest_challenge::set_attr(const t_parameter &p) { if (p.name == "realm") realm = p.value; else if (p.name == "nonce") nonce = p.value; else if (p.name == "opaque") opaque = p.value; else if (p.name == "algorithm") algorithm = p.value; else if (p.name == "domain") { vector l = split_ws(p.value); for (vector::iterator i = l.begin(); i != l.end(); i++) { t_url u(*i); if (u.is_valid()) { domain.push_back(u); } else { log_file->write_header("t_digest_challenge::set_attr", LOG_SIP, LOG_WARNING); log_file->write_raw("Invalid domain in digest challenge: "); log_file->write_raw(*i); log_file->write_endl(); log_file->write_footer(); } } } else if (p.name == "qop") { vector l = split(p.value, ','); for (vector::iterator i = l.begin(); i != l.end(); i++) { qop_options.push_back(trim(*i)); } } else if (p.name == "stale") { if (cmp_nocase(p.value, "true") == 0) stale = true; else // RFC 2617 3.2.1 // Any value other than false should be interpreted // as false. stale = false; } else auth_params.push_back(p); return true; } string t_challenge::encode(void) const { string s = auth_scheme; s += ' '; if (cmp_nocase(auth_scheme,AUTH_DIGEST) == 0) { s += digest_challenge.encode(); } else { for (list::const_iterator i = auth_params.begin(); i != auth_params.end(); i++) { if (i != auth_params.begin()) s += ','; s += i->encode(); } } return s; }