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