pear/auth_sasl
PEAR Auth_SASL is a PHP library for SASL authentication, providing PLAIN, LOGIN, CRAM-MD5, DIGEST-MD5, NTLM, SCRAM, anonymous, and external mechanisms. It helps PHP apps build SASL responses for IMAP, SMTP, LDAP, and other protocols.
pear/auth_sasl is a low-level PEAR library, not a Laravel package. It has no service provider, facade, config file, or Laravel integration. Treat it as a narrow utility for generating SASL authentication responses when you must speak a legacy protocol directly.
Minimal steps:
Install it:
composer require pear/auth_sasl
Verify Composer autoloading. PEAR packages use legacy underscore class names such as Auth_SASL and Auth_SASL_DigestMD5:
php artisan tinker
class_exists(\Auth_SASL::class); // true
Look first at:
vendor/pear/auth_sasl/Auth/SASL.php — the factory() switch and supported mechanism names.vendor/pear/auth_sasl/Auth/SASL/*.php — each mechanism’s getResponse() signature. They are not identical.vendor/composer/autoload_classmap.php if the class is not found.First real use case: authenticating against a legacy SMTP/IMAP service that requires a mechanism Laravel/Symfony Mailer does not expose, or generating a SASL token for a diagnostic command. For example, a basic PLAIN response:
$sasl = \Auth_SASL::factory('PLAIN');
if (!is_object($sasl) || !method_exists($sasl, 'getResponse')) {
throw new RuntimeException('SASL mechanism unavailable');
}
$token = $sasl->getResponse([
'authcid' => config('mail.mailers.smtp.username'),
'authzid' => '',
], config('mail.mailers.smtp.password'));
Do not reach for this package for ordinary Laravel mail. Symfony Mailer already handles PLAIN, LOGIN, CRAM-MD5, and XOAUTH2. Use pear/auth_sasl only when you need a mechanism Symfony does not provide, or when maintaining an integration that already depends on PEAR’s Net_SMTP.
Wrap it behind an application service. Do not call Auth_SASL::factory() throughout controllers or jobs. Isolate mechanism-specific signatures and PEAR error handling:
namespace App\Support;
final class SaslAuthenticator
{
public function plain(string $username, string $password, string $authzid = ''): string
{
return $this->factory('PLAIN')->getResponse([
'authcid' => $username,
'authzid' => $authzid,
], $password);
}
public function cramMd5(string $challenge, string $username, string $password): string
{
return $this->factory('CRAM-MD5')->getResponse(
$challenge,
['authcid' => $username],
$password
);
}
private function factory(string $mechanism): object
{
$sasl = \Auth_SASL::factory($mechanism);
if (!is_object($sasl) || !method_exists($sasl, 'getResponse')) {
throw new \RuntimeException("Unsupported SASL mechanism [{$mechanism}]");
}
return $sasl;
}
}
Bind this in a service provider if you use it in multiple places. This also gives you a seam to replace Auth_SASL later with a maintained SCRAM/SASL implementation.
Use it in a custom Symfony Mailer authenticator. If you need DIGEST-MD5 or NTLM for an SMTP server, implement Symfony\Component\Mailer\Transport\Smtp\Auth\AuthenticatorInterface and call Auth_SASL from authenticate(). Register the authenticator on an EsmtpTransport instance or from a custom transport factory. This keeps Laravel’s mail API intact while extending only the authentication step.
Use it in a legacy PEAR stack. If an existing project uses pear/net_smtp or pear/mail, Auth_SASL is already a transitive dependency. Configure the mechanism through Net_SMTP rather than calling Auth_SASL directly, unless you need to debug the token flow.
Build a reusable protocol health check. An Artisan command that connects to an SMTP server, reads the EHLO AUTH capabilities, chooses the strongest mutually supported mechanism, and generates a response with Auth_SASL is a practical diagnostic tool. Keep credentials in config and redact tokens from output.
Test with known vectors. PLAIN and LOGIN are easy to assert exactly. CRAM-MD5 has stable RFC test vectors. DIGEST-MD5 and NTLM are stateful and may include a random client nonce, so assert protocol flow and response structure rather than exact bytes unless you can inject deterministic values.
Create one instance per authentication session. Challenge-response mechanisms can retain challenge/state internally. Do not register a configured Auth_SASL object as a singleton and reuse it across users or connections.
Auth_SASL::factory() can return a PEAR_Error object for an unknown mechanism. PHP try/catch will not catch it. Check PEAR::isError() if PEAR core is available, or at minimum check is_object($sasl) and method_exists($sasl, 'getResponse').getResponse() signatures vary by mechanism. PLAIN and LOGIN generally take ($authData, $password). CRAM-MD5, DIGEST-MD5, and NTLM are challenge-response and generally take ($challenge, $authData, $password). Always read the concrete mechanism class before integrating.Auth_SASL_Login commonly returns base64 username and base64 password separated by \r\n, not one SMTP token. If you send it as a single AUTH response, the server may reject it. Split and send each line in response to the appropriate 334 challenge.rspauth verification. Treat it as a multi-step protocol, not a drop-in token generator.class_exists('Auth_SASL') is false after install, run composer dump-autoload and inspect Composer’s classmap. Avoid editing files under vendor/; if necessary, add a small bootstrap that requires the package’s Auth/SASL.php from a known path.Auth_SASL::factory() without an argument may default to DIGEST-MD5. Always pass the mechanism explicitly.'PLAIN', 'LOGIN', 'CRAM-MD5', 'DIGEST-MD5', and 'NTLM' as expected by the factory switch. The factory normalizes case, but the mechanism must still be supported by the installed version.config/mail.php or your own config file. Wrap the package in your own adapter so you can swap it for Symfony authenticators or another library without touching call sites.composer.json, run your test suite on the target PHP version, and watch for deprecation notices. The package is safest as a temporary compatibility adapter, not a core dependency.How can I help you explore Laravel packages today?