/**********
This library is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the
Free Software Foundation; either version 3 of the License, or (at your
option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)

This library 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 Lesser General Public License for
more details.

You should have received a copy of the GNU Lesser General Public License
along with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
**********/
// "liveMedia"
// Copyright (c) 1996-2020 Live Networks, Inc.  All rights reserved.
// A class used for digest authentication.
// Implementation

#include "DigestAuthentication.hh"
#include "ourMD5.hh"
#include <strDup.hh>
#include <GroupsockHelper.hh> // for gettimeofday()
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

Authenticator::Authenticator() {
  assign(NULL, NULL, NULL, NULL, False);
}

Authenticator::Authenticator(char const* username, char const* password, Boolean passwordIsMD5) {
  assign(NULL, NULL, username, password, passwordIsMD5);
}

Authenticator::Authenticator(const Authenticator& orig) {
  assign(orig.realm(), orig.nonce(), orig.username(), orig.password(), orig.fPasswordIsMD5);
}

Authenticator& Authenticator::operator=(const Authenticator& rightSide) {
  if (&rightSide != this) {
    reset();
    assign(rightSide.realm(), rightSide.nonce(),
	   rightSide.username(), rightSide.password(), rightSide.fPasswordIsMD5);
  }

  return *this;
}

Boolean Authenticator::operator<(const Authenticator* rightSide) {
  // Returns True if "rightSide" is 'newer' than us:
  if (rightSide != NULL && rightSide != this &&
      (rightSide->realm() != NULL || rightSide->nonce() != NULL ||
       username() == NULL || password() == NULL ||
       strcmp(rightSide->username(), username()) != 0 ||
       strcmp(rightSide->password(), password()) != 0)) {
    return True;
  }

  return False;
}

Authenticator::~Authenticator() {
  reset();
}

void Authenticator::reset() {
  resetRealmAndNonce();
  resetUsernameAndPassword();
}

void Authenticator::setRealmAndNonce(char const* realm, char const* nonce) {
  resetRealmAndNonce();
  assignRealmAndNonce(realm, nonce);
}

void Authenticator::setRealmAndRandomNonce(char const* realm) {
  resetRealmAndNonce();

  // Construct data to seed the random nonce:
  struct {
    struct timeval timestamp;
    unsigned counter;
  } seedData;
  gettimeofday(&seedData.timestamp, NULL);
  static unsigned counter = 0;
  seedData.counter = ++counter;

  // Use MD5 to compute a 'random' nonce from this seed data:
  char nonceBuf[33];
  our_MD5Data((unsigned char*)(&seedData), sizeof seedData, nonceBuf);

  assignRealmAndNonce(realm, nonceBuf);
}

void Authenticator::setUsernameAndPassword(char const* username,
					   char const* password,
					   Boolean passwordIsMD5) {
  resetUsernameAndPassword();
  assignUsernameAndPassword(username, password, passwordIsMD5);
}

char const* Authenticator::computeDigestResponse(char const* cmd,
						 char const* url) const {
  // The "response" field is computed as:
  //    md5(md5(<username>:<realm>:<password>):<nonce>:md5(<cmd>:<url>))
  // or, if "fPasswordIsMD5" is True:
  //    md5(<password>:<nonce>:md5(<cmd>:<url>))
  char ha1Buf[33];
  if (fPasswordIsMD5) {
    strncpy(ha1Buf, password(), 32);
    ha1Buf[32] = '\0'; // just in case
  } else {
    unsigned const ha1DataLen = strlen(username()) + 1
      + strlen(realm()) + 1 + strlen(password());
    unsigned char* ha1Data = new unsigned char[ha1DataLen+1];
    sprintf((char*)ha1Data, "%s:%s:%s", username(), realm(), password());
    our_MD5Data(ha1Data, ha1DataLen, ha1Buf);
    delete[] ha1Data;
  }

  unsigned const ha2DataLen = strlen(cmd) + 1 + strlen(url);
  unsigned char* ha2Data = new unsigned char[ha2DataLen+1];
  sprintf((char*)ha2Data, "%s:%s", cmd, url);
  char ha2Buf[33];
  our_MD5Data(ha2Data, ha2DataLen, ha2Buf);
  delete[] ha2Data;

  unsigned const digestDataLen
    = 32 + 1 + strlen(nonce()) + 1 + 32;
  unsigned char* digestData = new unsigned char[digestDataLen+1];
  sprintf((char*)digestData, "%s:%s:%s",
          ha1Buf, nonce(), ha2Buf);
  char const* result = our_MD5Data(digestData, digestDataLen, NULL);
  delete[] digestData;
  return result;
}

void Authenticator::reclaimDigestResponse(char const* responseStr) const {
  delete[](char*)responseStr;
}

void Authenticator::resetRealmAndNonce() {
  delete[] fRealm; fRealm = NULL;
  delete[] fNonce; fNonce = NULL;
}

void Authenticator::resetUsernameAndPassword() {
  delete[] fUsername; fUsername = NULL;
  delete[] fPassword; fPassword = NULL;
  fPasswordIsMD5 = False;
}

void Authenticator::assignRealmAndNonce(char const* realm, char const* nonce) {
  fRealm = strDup(realm);
  fNonce = strDup(nonce);
}

void Authenticator::assignUsernameAndPassword(char const* username, char const* password, Boolean passwordIsMD5) {
  if (username == NULL) username = "";
  if (password == NULL) password = "";

  fUsername = strDup(username);
  fPassword = strDup(password);
  fPasswordIsMD5 = passwordIsMD5;
}

void Authenticator::assign(char const* realm, char const* nonce,
			   char const* username, char const* password, Boolean passwordIsMD5) {
  assignRealmAndNonce(realm, nonce);
  assignUsernameAndPassword(username, password, passwordIsMD5);
}
