reSIProcate/stack  9694
testDigestAuthentication2.cxx
Go to the documentation of this file.
00001 #include <assert.h>
00002 #include <iostream>
00003 #include <string.h>
00004 #ifdef WIN32
00005 #include <io.h>
00006 #else
00007 #include <unistd.h>
00008 #endif
00009 #include <memory>
00010 
00011 #ifdef WIN32
00012 #define usleep(x) Sleep(x/1000)
00013 #define sleep(x) Sleep(x*1000)
00014 #endif
00015 
00016 #include "resip/stack/HeaderFieldValue.hxx"
00017 #include "resip/stack/HeaderTypes.hxx"
00018 #include "resip/stack/ParserCategories.hxx"
00019 #include "resip/stack/Uri.hxx"
00020 #include "resip/stack/Helper.hxx"
00021 #include "resip/stack/test/TestSupport.hxx"
00022 #include "rutil/Timer.hxx"
00023 #include "rutil/DataStream.hxx"
00024 #include "rutil/MD5Stream.hxx"
00025 #include "digcalc.hxx"
00026 #include "rutil/Logger.hxx"
00027 
00028 #define RESIPROCATE_SUBSYSTEM resip::Subsystem::TEST
00029 
00030 using namespace std;
00031 using namespace resip;
00032 
00033 int
00034 main(int arc, char** argv)
00035 {
00036 
00037    {
00038       char* alg = "MD5";
00039       char* username = "user";
00040       char* password = "secret";
00041       char* realm = "localhost";
00042       char* method = "REGISTER";
00043       char* uri = "user@host.com";
00044       char* nonce = "92347fea23";
00045 
00046 
00047       MD5Stream a1;
00048       a1 << username
00049          << Symbols::COLON
00050          << realm
00051          << Symbols::COLON
00052          << password;
00053       Data passwordHashA1 = a1.getHex();
00054 
00055 
00056       Data responseMD5withA1 = Helper::makeResponseMD5WithA1(passwordHashA1,
00057                                                        method,
00058                                                        uri,
00059                                                        nonce);
00060 
00061 
00062       Data responseMD5 = Helper::makeResponseMD5(username,
00063                                                  password,
00064                                                  realm,
00065                                                  method,
00066                                                  uri,
00067                                                  nonce);
00068       
00069       HASHHEX a1Hash;
00070       HASHHEX response;
00071 
00072       DigestCalcHA1(alg,
00073                     username,
00074                     realm,
00075                     password,
00076                     nonce,
00077                     (char*)"",
00078                     a1Hash);
00079 
00080       DigestCalcResponse(a1Hash,
00081                          nonce,
00082                          (char*)"",
00083                          (char*)"",
00084                          (char*)"",
00085                          method,
00086                          uri,
00087                          (char*)"",
00088                          response);
00089 
00090       assert(responseMD5 == response);
00091       assert(responseMD5withA1 == response);
00092    }
00093 
00094 
00095 
00096    {
00097       Data txt("INVITE sip:bob@biloxi.com SIP/2.0\r\n"
00098                "Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8\r\n"
00099                "To: Bob <sip:bob@biloxi.com>\r\n"
00100                "From: Alice <sip:alice@atlanta.com>;tag=1928301774\r\n"
00101                "Call-ID: a84b4c76e66710\r\n"
00102                "CSeq: 314159 INVITE\r\n"
00103                "Max-Forwards: 70\r\n"
00104                "Contact: <sip:alice@pc33.atlanta.com>\r\n"
00105                "Content-Type: application/sdp\r\n"
00106                "Content-Length: 150\r\n"
00107                "\r\n"
00108                "v=0\r\n"
00109                "o=alice 53655765 2353687637 IN IP4 pc33.atlanta.com\r\n"
00110                "s=-\r\n"
00111                "c=IN IP4 pc33.atlanta.com\r\n"
00112                "t=0 0\r\n"
00113                "m=audio 3456 RTP/AVP 0 1 3 99\r\n"
00114                "a=rtpmap:0 PCMU/8000\r\n");
00115       
00116       auto_ptr<SipMessage> request(TestSupport::makeMessage(txt.c_str()));      
00117 
00118       Data realm = "localhost";
00119       auto_ptr<SipMessage> challenge(Helper::makeProxyChallenge(*request, realm, false));
00120 
00121       assert(challenge->exists(h_ProxyAuthenticates));
00122       assert(challenge->header(h_ProxyAuthenticates).size() == 1);
00123 
00124       Data username = "bob";
00125       Data password = "secret";
00126       Data cnonce;// = "366fead6";
00127       unsigned int nc = 0;
00128       MD5Stream a1;
00129       a1 << username
00130          << Symbols::COLON
00131          << realm
00132          << Symbols::COLON
00133          << password;
00134       Data passwordHashA1 = a1.getHex();
00135       InfoLog (<< "passwordHashA1=" << passwordHashA1);
00136       Data cnonceRet;
00137       request->header(h_ProxyAuthorizations).push_back( Helper::makeChallengeResponseAuthWithA1(*request,
00138                                                                                                 username, 
00139                                                                                                 passwordHashA1,
00140                                                                                                 *(challenge->header(h_ProxyAuthenticates).begin()),
00141                                                                                                 cnonce,
00142                                                                                                 nc,
00143                                                                                                 cnonceRet));
00144 
00145       assert(request->exists(h_ProxyAuthorizations));
00146       assert(request->header(h_ProxyAuthorizations).size() == 1);
00147       assert(!request->header(h_ProxyAuthorizations).front().exists(p_qop));
00148 
00149       const Auth& auth = request->header(h_ProxyAuthorizations).front();
00150       
00151       assert(auth.param(p_username) == "bob");
00152       assert(auth.param(p_uri) == "sip:bob@biloxi.com");
00153       assert(auth.param(p_algorithm) == "MD5");
00154 
00155       Helper::AuthResult res = Helper::authenticateRequest(*request, 
00156                                                            realm,
00157                                                            password);
00158       assert(res == Helper::Authenticated);
00159 
00160       res = Helper::authenticateRequest(*request, 
00161                                         realm,
00162                                         password.md5(),
00163                                         5);
00164 
00165       assert(res == Helper::Authenticated);
00166 
00167       sleep(2);
00168       res = Helper::authenticateRequest(*request, 
00169                                         realm,
00170                                         password.md5(),
00171                                         1);
00172  
00173       assert(res == Helper::Expired);
00174       
00175    }
00176 
00177    cerr << "ALL OK" << endl;
00178    return 0;
00179 }
00180 /* ====================================================================
00181  * The Vovida Software License, Version 1.0 
00182  * 
00183  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
00184  * 
00185  * Redistribution and use in source and binary forms, with or without
00186  * modification, are permitted provided that the following conditions
00187  * are met:
00188  * 
00189  * 1. Redistributions of source code must retain the above copyright
00190  *    notice, this list of conditions and the following disclaimer.
00191  * 
00192  * 2. Redistributions in binary form must reproduce the above copyright
00193  *    notice, this list of conditions and the following disclaimer in
00194  *    the documentation and/or other materials provided with the
00195  *    distribution.
00196  * 
00197  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
00198  *    and "Vovida Open Communication Application Library (VOCAL)" must
00199  *    not be used to endorse or promote products derived from this
00200  *    software without prior written permission. For written
00201  *    permission, please contact vocal@vovida.org.
00202  *
00203  * 4. Products derived from this software may not be called "VOCAL", nor
00204  *    may "VOCAL" appear in their name, without prior written
00205  *    permission of Vovida Networks, Inc.
00206  * 
00207  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
00208  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00209  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
00210  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
00211  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
00212  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
00213  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00214  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00215  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
00216  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00217  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00218  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
00219  * DAMAGE.
00220  * 
00221  * ====================================================================
00222  * 
00223  * This software consists of voluntary contributions made by Vovida
00224  * Networks, Inc. and many individuals on behalf of Vovida Networks,
00225  * Inc.  For more information on Vovida Networks, Inc., please see
00226  * <http://www.vovida.org/>.
00227  *
00228  */