Example #1
0
 function Authenticate(&$headers, $proxy, &$proxy_authorization, &$user, &$password, &$realm, &$workstation)
 {
     if ($proxy) {
         $authenticate_header = "proxy-authenticate";
         $authorization_header = "Proxy-Authorization";
         $authenticate_status = "407";
         $authentication_mechanism = $this->proxy_authentication_mechanism;
     } else {
         $authenticate_header = "www-authenticate";
         $authorization_header = "Authorization";
         $authenticate_status = "401";
         $authentication_mechanism = $this->authentication_mechanism;
     }
     if (isset($headers[$authenticate_header])) {
         if (function_exists("class_exists") && !class_exists("sasl_client_class", 0)) {
             return $this->SetError("the SASL client class needs to be loaded to be able to authenticate" . ($proxy ? " with the proxy server" : "") . " and access this site");
         }
         if (GetType($headers[$authenticate_header]) == "array") {
             $authenticate = $headers[$authenticate_header];
         } else {
             $authenticate = array($headers[$authenticate_header]);
         }
         for ($response = "", $mechanisms = array(), $m = 0; $m < count($authenticate); $m++) {
             $mechanism = $this->Tokenize($authenticate[$m], " ");
             $response = $this->Tokenize("");
             if (strlen($authentication_mechanism)) {
                 if (!strcmp($authentication_mechanism, $mechanism)) {
                     $mechanisms[] = $mechanism;
                     break;
                 }
             } else {
                 $mechanisms[] = $mechanism;
             }
         }
         $sasl = new sasl_client_class();
         if (isset($user)) {
             $sasl->SetCredential("user", $user);
         }
         if (isset($password)) {
             $sasl->SetCredential("password", $password);
         }
         if (isset($realm)) {
             $sasl->SetCredential("realm", $realm);
         }
         if (isset($workstation)) {
             $sasl->SetCredential("workstation", $workstation);
         }
         $sasl->SetCredential("uri", $this->request_uri);
         $sasl->SetCredential("method", $this->request_method);
         $sasl->SetCredential("session", $this->session);
         do {
             $status = $sasl->Start($mechanisms, $message, $interactions);
         } while ($status == SASL_INTERACT);
         switch ($status) {
             case SASL_CONTINUE:
                 break;
             case SASL_NOMECH:
                 return $this->SetError(($proxy ? "proxy " : "") . "authentication error: " . (strlen($authentication_mechanism) ? "authentication mechanism " . $authentication_mechanism . " may not be used: " : "") . $sasl->error);
             default:
                 return $this->SetError("Could not start the SASL " . ($proxy ? "proxy " : "") . "authentication client: " . $sasl->error);
         }
         if ($proxy >= 0) {
             for (;;) {
                 if (strlen($error = $this->ReadReplyBody($body, $this->file_buffer_length))) {
                     return $error;
                 }
                 if (strlen($body) == 0) {
                     break;
                 }
             }
         }
         $authorization_value = $sasl->mechanism . (isset($message) ? " " . ($sasl->encode_response ? base64_encode($message) : $message) : "");
         $request_arguments = $this->request_arguments;
         $arguments = $request_arguments;
         $arguments["Headers"][$authorization_header] = $authorization_value;
         if (!$proxy && strlen($proxy_authorization)) {
             $arguments["Headers"]["Proxy-Authorization"] = $proxy_authorization;
         }
         if (strlen($error = $this->Close()) || strlen($error = $this->Open($arguments))) {
             return $this->SetError($error);
         }
         $authenticated = 0;
         if (isset($message)) {
             if ($proxy < 0) {
                 if (strlen($error = $this->ConnectFromProxy($arguments, $headers))) {
                     return $this->SetError($error);
                 }
             } else {
                 if (strlen($error = $this->SendRequest($arguments)) || strlen($error = $this->ReadReplyHeadersResponse($headers))) {
                     return $this->SetError($error);
                 }
             }
             if (!isset($headers[$authenticate_header])) {
                 $authenticate = array();
             } elseif (GetType($headers[$authenticate_header]) == "array") {
                 $authenticate = $headers[$authenticate_header];
             } else {
                 $authenticate = array($headers[$authenticate_header]);
             }
             for ($mechanism = 0; $mechanism < count($authenticate); $mechanism++) {
                 if (!strcmp($this->Tokenize($authenticate[$mechanism], " "), $sasl->mechanism)) {
                     $response = $this->Tokenize("");
                     break;
                 }
             }
             switch ($this->response_status) {
                 case $authenticate_status:
                     break;
                 case "301":
                 case "302":
                 case "303":
                 case "307":
                     if ($proxy >= 0) {
                         return $this->Redirect($headers);
                     }
                 default:
                     if (intval($this->response_status / 100) == 2) {
                         if ($proxy) {
                             $proxy_authorization = $authorization_value;
                         }
                         $authenticated = 1;
                         break;
                     }
                     if ($proxy && !strcmp($this->response_status, "401")) {
                         $proxy_authorization = $authorization_value;
                         $authenticated = 1;
                         break;
                     }
                     return $this->SetError(($proxy ? "proxy " : "") . "authentication error: " . $this->response_status . " " . $this->response_message);
             }
         }
         for (; !$authenticated;) {
             do {
                 $status = $sasl->Step($response, $message, $interactions);
             } while ($status == SASL_INTERACT);
             switch ($status) {
                 case SASL_CONTINUE:
                     $authorization_value = $sasl->mechanism . (isset($message) ? " " . ($sasl->encode_response ? base64_encode($message) : $message) : "");
                     $arguments = $request_arguments;
                     $arguments["Headers"][$authorization_header] = $authorization_value;
                     if (!$proxy && strlen($proxy_authorization)) {
                         $arguments["Headers"]["Proxy-Authorization"] = $proxy_authorization;
                     }
                     if ($proxy < 0) {
                         if (strlen($error = $this->ConnectFromProxy($arguments, $headers))) {
                             return $this->SetError($error);
                         }
                     } else {
                         if (strlen($error = $this->SendRequest($arguments)) || strlen($error = $this->ReadReplyHeadersResponse($headers))) {
                             return $this->SetError($error);
                         }
                     }
                     switch ($this->response_status) {
                         case $authenticate_status:
                             if (GetType($headers[$authenticate_header]) == "array") {
                                 $authenticate = $headers[$authenticate_header];
                             } else {
                                 $authenticate = array($headers[$authenticate_header]);
                             }
                             for ($response = "", $mechanism = 0; $mechanism < count($authenticate); $mechanism++) {
                                 if (!strcmp($this->Tokenize($authenticate[$mechanism], " "), $sasl->mechanism)) {
                                     $response = $this->Tokenize("");
                                     break;
                                 }
                             }
                             if ($proxy >= 0) {
                                 for (;;) {
                                     if (strlen($error = $this->ReadReplyBody($body, $this->file_buffer_length))) {
                                         return $error;
                                     }
                                     if (strlen($body) == 0) {
                                         break;
                                     }
                                 }
                             }
                             $this->state = "Connected";
                             break;
                         case "301":
                         case "302":
                         case "303":
                         case "307":
                             if ($proxy >= 0) {
                                 return $this->Redirect($headers);
                             }
                         default:
                             if (intval($this->response_status / 100) == 2) {
                                 if ($proxy) {
                                     $proxy_authorization = $authorization_value;
                                 }
                                 $authenticated = 1;
                                 break;
                             }
                             if ($proxy && !strcmp($this->response_status, "401")) {
                                 $proxy_authorization = $authorization_value;
                                 $authenticated = 1;
                                 break;
                             }
                             return $this->SetError(($proxy ? "proxy " : "") . "authentication error: " . $this->response_status . " " . $this->response_message);
                     }
                     break;
                 default:
                     return $this->SetError("Could not process the SASL " . ($proxy ? "proxy " : "") . "authentication step: " . $sasl->error);
             }
         }
     }
     return "";
 }
Example #2
0
 function SASLAuthenticate($mechanisms, $credentials, &$authenticated, &$mechanism)
 {
     $authenticated = 0;
     if (!function_exists("class_exists") || !class_exists("sasl_client_class")) {
         $this->error = "it is not possible to authenticate using the specified mechanism because the SASL library class is not loaded";
         return 0;
     }
     $sasl = new sasl_client_class();
     $sasl->SetCredential("user", $credentials["user"]);
     $sasl->SetCredential("password", $credentials["password"]);
     if (isset($credentials["realm"])) {
         $sasl->SetCredential("realm", $credentials["realm"]);
     }
     if (isset($credentials["workstation"])) {
         $sasl->SetCredential("workstation", $credentials["workstation"]);
     }
     if (isset($credentials["mode"])) {
         $sasl->SetCredential("mode", $credentials["mode"]);
     }
     do {
         $status = $sasl->Start($mechanisms, $message, $interactions);
     } while ($status == SASL_INTERACT);
     switch ($status) {
         case SASL_CONTINUE:
             break;
         case SASL_NOMECH:
             if (strlen($this->authentication_mechanism)) {
                 $this->error = "authenticated mechanism " . $this->authentication_mechanism . " may not be used: " . $sasl->error;
                 return 0;
             }
             break;
         default:
             $this->error = "Could not start the SASL authentication client: " . $sasl->error;
             return 0;
     }
     if (strlen($mechanism = $sasl->mechanism)) {
         if ($this->PutLine("AUTH " . $sasl->mechanism . (isset($message) ? " " . base64_encode($message) : "")) == 0) {
             $this->error = "Could not send the AUTH command";
             return 0;
         }
         if (!$this->VerifyResultLines(array("235", "334"), $responses)) {
             return 0;
         }
         switch ($this->result_code) {
             case "235":
                 $response = "";
                 $authenticated = 1;
                 break;
             case "334":
                 $response = base64_decode($responses[0]);
                 break;
             default:
                 $this->error = "Authentication error: " . $responses[0];
                 return 0;
         }
         for (; !$authenticated;) {
             do {
                 $status = $sasl->Step($response, $message, $interactions);
             } while ($status == SASL_INTERACT);
             switch ($status) {
                 case SASL_CONTINUE:
                     if ($this->PutLine(base64_encode($message)) == 0) {
                         $this->error = "Could not send the authentication step message";
                         return 0;
                     }
                     if (!$this->VerifyResultLines(array("235", "334"), $responses)) {
                         return 0;
                     }
                     switch ($this->result_code) {
                         case "235":
                             $response = "";
                             $authenticated = 1;
                             break;
                         case "334":
                             $response = base64_decode($responses[0]);
                             break;
                         default:
                             $this->error = "Authentication error: " . $responses[0];
                             return 0;
                     }
                     break;
                 default:
                     $this->error = "Could not process the SASL authentication step: " . $sasl->error;
                     return 0;
             }
         }
     }
     return 1;
 }
Example #3
0
 function Login($user, $password, $apop = 0)
 {
     if ($this->state != "AUTHORIZATION") {
         return $this->SetError("connection is not in AUTHORIZATION state");
     }
     if ($apop) {
         if (!strcmp($this->greeting, "")) {
             return $this->SetError("Server does not seem to support APOP authentication");
         }
         if ($this->PutLine("APOP {$user} " . md5("<" . $this->greeting . ">" . $password)) == 0) {
             return $this->SetError("Could not send the APOP command");
         }
         $response = $this->GetLine();
         if (GetType($response) != "string") {
             return $this->SetError("Could not get APOP login command response");
         }
         if ($this->Tokenize($response, " ") != "+OK") {
             return $this->SetError("APOP login failed: " . $this->Tokenize("\r\n"));
         }
     } else {
         $authenticated = 0;
         if (strcmp($this->authentication_mechanism, "USER") && function_exists("class_exists") && class_exists("sasl_client_class")) {
             if (strlen($this->authentication_mechanism)) {
                 $mechanisms = array($this->authentication_mechanism);
             } else {
                 $mechanisms = array();
                 if ($this->PutLine("CAPA") == 0) {
                     return $this->SetError("Could not send the CAPA command");
                 }
                 $response = $this->GetLine();
                 if (GetType($response) != "string") {
                     return $this->SetError("Could not get CAPA command response");
                 }
                 if (!strcmp($this->Tokenize($response, " "), "+OK")) {
                     for (;;) {
                         $response = $this->GetLine();
                         if (GetType($response) != "string") {
                             return $this->SetError("Could not retrieve the supported authentication methods");
                         }
                         switch ($this->Tokenize($response, " ")) {
                             case ".":
                                 break 2;
                             case "SASL":
                                 for ($method = 1; strlen($mechanism = $this->Tokenize(" ")); $method++) {
                                     $mechanisms[] = $mechanism;
                                 }
                                 break;
                         }
                     }
                 }
             }
             $sasl = new sasl_client_class();
             $sasl->SetCredential("user", $user);
             $sasl->SetCredential("password", $password);
             if (strlen($this->realm)) {
                 $sasl->SetCredential("realm", $this->realm);
             }
             if (strlen($this->workstation)) {
                 $sasl->SetCredential("workstation", $this->workstation);
             }
             do {
                 $status = $sasl->Start($mechanisms, $message, $interactions);
             } while ($status == SASL_INTERACT);
             switch ($status) {
                 case SASL_CONTINUE:
                     break;
                 case SASL_NOMECH:
                     if (strlen($this->authentication_mechanism)) {
                         return $this->SetError("authenticated mechanism " . $this->authentication_mechanism . " may not be used: " . $sasl->error);
                     }
                     break;
                 default:
                     return $this->SetError("Could not start the SASL authentication client: " . $sasl->error);
             }
             if (strlen($sasl->mechanism)) {
                 if ($this->PutLine("AUTH " . $sasl->mechanism . (isset($message) ? " " . base64_encode($message) : "")) == 0) {
                     return "Could not send the AUTH command";
                 }
                 $response = $this->GetLine();
                 if (GetType($response) != "string") {
                     return "Could not get AUTH command response";
                 }
                 switch ($this->Tokenize($response, " ")) {
                     case "+OK":
                         $response = "";
                         break;
                     case "+":
                         $response = base64_decode($this->Tokenize("\r\n"));
                         break;
                     default:
                         return $this->SetError("Authentication error: " . $this->Tokenize("\r\n"));
                 }
                 for (; !$authenticated;) {
                     do {
                         $status = $sasl->Step($response, $message, $interactions);
                     } while ($status == SASL_INTERACT);
                     switch ($status) {
                         case SASL_CONTINUE:
                             if ($this->PutLine(base64_encode($message)) == 0) {
                                 return "Could not send message authentication step message";
                             }
                             $response = $this->GetLine();
                             if (GetType($response) != "string") {
                                 return "Could not get authentication step message response";
                             }
                             switch ($this->Tokenize($response, " ")) {
                                 case "+OK":
                                     $authenticated = 1;
                                     break;
                                 case "+":
                                     $response = base64_decode($this->Tokenize("\r\n"));
                                     break;
                                 default:
                                     return $this->SetError("Authentication error: " . $this->Tokenize("\r\n"));
                             }
                             break;
                         default:
                             return $this->SetError("Could not process the SASL authentication step: " . $sasl->error);
                     }
                 }
             }
         }
         if (!$authenticated) {
             if ($this->PutLine("USER {$user}") == 0) {
                 return $this->SetError("Could not send the USER command");
             }
             $response = $this->GetLine();
             if (GetType($response) != "string") {
                 return $this->SetError("Could not get user login entry response");
             }
             if ($this->Tokenize($response, " ") != "+OK") {
                 return $this->SetError("User error: " . $this->Tokenize("\r\n"));
             }
             if ($this->PutLine("PASS {$password}") == 0) {
                 return $this->SetError("Could not send the PASS command");
             }
             $response = $this->GetLine();
             if (GetType($response) != "string") {
                 return $this->SetError("Could not get login password entry response");
             }
             if ($this->Tokenize($response, " ") != "+OK") {
                 return $this->SetError("Password error: " . $this->Tokenize("\r\n"));
             }
         }
     }
     $this->state = "TRANSACTION";
     return "";
 }