00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "DigestAuthentication.hh"
00022 #include "our_md5.h"
00023 #include <strDup.hh>
00024 #include <GroupsockHelper.hh>
00025 #include <stdio.h>
00026 #include <stdlib.h>
00027 #include <string.h>
00028
00029 Authenticator::Authenticator() {
00030 assign(NULL, NULL, NULL, NULL, False);
00031 }
00032
00033 Authenticator::Authenticator(const Authenticator& orig) {
00034 assign(orig.realm(), orig.nonce(), orig.username(), orig.password(),
00035 orig.fPasswordIsMD5);
00036 }
00037
00038 Authenticator& Authenticator::operator=(const Authenticator& rightSide) {
00039 if (&rightSide != this) {
00040 reset();
00041 assign(rightSide.realm(), rightSide.nonce(),
00042 rightSide.username(), rightSide.password(), rightSide.fPasswordIsMD5);
00043 }
00044
00045 return *this;
00046 }
00047
00048 Authenticator::~Authenticator() {
00049 reset();
00050 }
00051
00052 void Authenticator::reset() {
00053 resetRealmAndNonce();
00054 resetUsernameAndPassword();
00055 }
00056
00057 void Authenticator::setRealmAndNonce(char const* realm, char const* nonce) {
00058 resetRealmAndNonce();
00059 assignRealmAndNonce(realm, nonce);
00060 }
00061
00062 void Authenticator::setRealmAndRandomNonce(char const* realm) {
00063 resetRealmAndNonce();
00064
00065
00066 struct {
00067 struct timeval timestamp;
00068 unsigned counter;
00069 } seedData;
00070 gettimeofday(&seedData.timestamp, NULL);
00071 static unsigned counter = 0;
00072 seedData.counter = ++counter;
00073
00074
00075 char nonceBuf[33];
00076 our_MD5Data((unsigned char*)(&seedData), sizeof seedData, nonceBuf);
00077
00078 assignRealmAndNonce(realm, nonceBuf);
00079 }
00080
00081 void Authenticator::setUsernameAndPassword(char const* username,
00082 char const* password,
00083 Boolean passwordIsMD5) {
00084 resetUsernameAndPassword();
00085 assignUsernameAndPassword(username, password, passwordIsMD5);
00086 }
00087
00088 char const* Authenticator::computeDigestResponse(char const* cmd,
00089 char const* url) const {
00090
00091
00092
00093
00094 char ha1Buf[33];
00095 if (fPasswordIsMD5) {
00096 strncpy(ha1Buf, password(), 32);
00097 ha1Buf[32] = '\0';
00098 } else {
00099 unsigned const ha1DataLen = strlen(username()) + 1
00100 + strlen(realm()) + 1 + strlen(password());
00101 unsigned char* ha1Data = new unsigned char[ha1DataLen+1];
00102 sprintf((char*)ha1Data, "%s:%s:%s", username(), realm(), password());
00103 our_MD5Data(ha1Data, ha1DataLen, ha1Buf);
00104 delete[] ha1Data;
00105 }
00106
00107 unsigned const ha2DataLen = strlen(cmd) + 1 + strlen(url);
00108 unsigned char* ha2Data = new unsigned char[ha2DataLen+1];
00109 sprintf((char*)ha2Data, "%s:%s", cmd, url);
00110 char ha2Buf[33];
00111 our_MD5Data(ha2Data, ha2DataLen, ha2Buf);
00112 delete[] ha2Data;
00113
00114 unsigned const digestDataLen
00115 = 32 + 1 + strlen(nonce()) + 1 + 32;
00116 unsigned char* digestData = new unsigned char[digestDataLen+1];
00117 sprintf((char*)digestData, "%s:%s:%s",
00118 ha1Buf, nonce(), ha2Buf);
00119 char const* result = our_MD5Data(digestData, digestDataLen, NULL);
00120 delete[] digestData;
00121 return result;
00122 }
00123
00124 void Authenticator::reclaimDigestResponse(char const* responseStr) const {
00125 free((char*)responseStr);
00126 }
00127
00128 void Authenticator::resetRealmAndNonce() {
00129 delete[] fRealm; fRealm = NULL;
00130 delete[] fNonce; fNonce = NULL;
00131 }
00132
00133 void Authenticator::resetUsernameAndPassword() {
00134 delete[] fUsername; fUsername = NULL;
00135 delete[] fPassword; fPassword = NULL;
00136 fPasswordIsMD5 = False;
00137 }
00138
00139 void Authenticator::assignRealmAndNonce(char const* realm, char const* nonce) {
00140 fRealm = strDup(realm);
00141 fNonce = strDup(nonce);
00142 }
00143
00144 void Authenticator
00145 ::assignUsernameAndPassword(char const* username, char const* password,
00146 Boolean passwordIsMD5) {
00147 fUsername = strDup(username);
00148 fPassword = strDup(password);
00149 fPasswordIsMD5 = passwordIsMD5;
00150 }
00151
00152 void Authenticator::assign(char const* realm, char const* nonce,
00153 char const* username, char const* password,
00154 Boolean passwordIsMD5) {
00155 assignRealmAndNonce(realm, nonce);
00156 assignUsernameAndPassword(username, password, passwordIsMD5);
00157 }