H($secret.':'.$data); } Function Initialize(&$client) { return(1); } Function Start(&$client, &$message, &$interactions) { if($this->state!=SASL_DIGEST_STATE_START) { $client->error='Digest authentication state is not at the start'; return(SASL_FAIL); } $this->credentials=array( 'user'=>'', 'password'=>'', 'uri'=>'', 'method'=>'', 'session'=>'' ); $defaults=array(); $status=$client->GetCredentials($this->credentials,$defaults,$interactions); if($status==SASL_CONTINUE) $this->state=SASL_DIGEST_STATE_RESPOND_CHALLENGE; Unset($message); return($status); } Function Step(&$client, $response, &$message, &$interactions) { switch($this->state) { case SASL_DIGEST_STATE_RESPOND_CHALLENGE: $values=explode(',',$response); $parameters=array(); for($v=0; $vcredentials['user'].'"'; if(!IsSet($parameters[$p='realm']) && !IsSet($parameters[$p='nonce'])) { $client->error='Digest authentication parameter '.$p.' is missing from the server response'; return(SASL_FAIL); } $message.=', realm='.$parameters['realm']; $message.=', nonce='.$parameters['nonce']; $message.=', uri="'.$this->credentials['uri'].'"'; if(IsSet($parameters['algorithm'])) { $algorithm=$this->unq($parameters['algorithm']); $message.=', algorithm='.$parameters['algorithm']; } else $algorithm=''; $realm=$this->unq($parameters['realm']); $nonce=$this->unq($parameters['nonce']); if(IsSet($parameters['qop'])) { switch($qop=$this->unq($parameters['qop'])) { case "auth": $cnonce=$this->credentials['session']; break; default: $client->error='Digest authentication quality of protection '.$qop.' is not yet supported'; return(SASL_FAIL); } } $nc_value='00000001'; if(IsSet($parameters['qop']) && !strcmp($algorithm, 'MD5-sess')) $A1=$this->H($this->credentials['user'].':'. $realm.':'. $this->credentials['password']).':'.$nonce.':'.$cnonce; else $A1=$this->credentials['user'].':'. $realm.':'. $this->credentials['password']; $A2=$this->credentials['method'].':'.$this->credentials['uri']; if(IsSet($parameters['qop'])) $response=$this->KD($this->H($A1), $nonce.':'. $nc_value.':'. $cnonce.':'. $qop.':'. $this->H($A2)); else $response=$this->KD($this->H($A1), $nonce.':'. $this->H($A2)); $message.=', response="'.$response.'"'; if(IsSet($parameters['opaque'])) $message.=', opaque='.$parameters['opaque']; if(IsSet($parameters['qop'])) $message.=', qop="'.$qop.'"'; $message.=', nc='.$nc_value; if(IsSet($parameters['qop'])) $message.=', cnonce="'.$cnonce.'"'; $client->encode_response=0; $this->state=SASL_DIGEST_STATE_DONE; break; case SASL_DIGEST_STATE_DONE: $client->error='Digest authentication was finished without success'; return(SASL_FAIL); default: $client->error='invalid Digest authentication step state'; return(SASL_FAIL); } return(SASL_CONTINUE); } }; ?>