@@ -162,6 +162,13 @@ class Net_SMTP
162
162
*/
163
163
protected $ gssapi_cname = null ;
164
164
165
+ /**
166
+ * SCRAM SHA-Hash algorithm.
167
+ *
168
+ * @var string
169
+ */
170
+ protected $ scram_sha_hash_algorithm = null ;
171
+
165
172
/**
166
173
* Instantiates a new Net_SMTP object, overriding any defaults
167
174
* with parameters that are passed in.
@@ -215,6 +222,11 @@ public function __construct($host = null, $port = null, $localhost = null,
215
222
if (@include_once 'Auth/SASL.php ' ) {
216
223
$ this ->setAuthMethod ('CRAM-MD5 ' , array ($ this , 'authCramMD5 ' ));
217
224
$ this ->setAuthMethod ('DIGEST-MD5 ' , array ($ this , 'authDigestMD5 ' ));
225
+ $ this ->setAuthMethod ('SCRAM-SHA-1 ' , array ($ this , 'authScramSHA1 ' ));
226
+ $ this ->setAuthMethod ('SCRAM-SHA-224 ' , array ($ this , 'authScramSHA224 ' ));
227
+ $ this ->setAuthMethod ('SCRAM-SHA-256 ' , array ($ this , 'authScramSHA256 ' ));
228
+ $ this ->setAuthMethod ('SCRAM-SHA-384 ' , array ($ this , 'authScramSHA384 ' ));
229
+ $ this ->setAuthMethod ('SCRAM-SHA-512 ' , array ($ this , 'authScramSHA512 ' ));
218
230
}
219
231
220
232
/* These standard authentication methods are always available. */
@@ -819,9 +831,13 @@ public function setAuthMethod($name, $callback, $prepend = true)
819
831
* @return mixed Returns a PEAR_Error with an error message on any
820
832
* kind of failure, or true on success.
821
833
* @since 1.1.0
834
+ * @deprecated 1.11.0
822
835
*/
823
836
protected function authDigestMD5 ($ uid , $ pwd , $ authz = '' )
824
837
{
838
+ trigger_error (__CLASS__ . ' ( ' . $ this ->host . '): Authentication method DIGEST-MD5 ' .
839
+ ' is no longer secure and should be avoided. ' , E_USER_DEPRECATED );
840
+
825
841
if (PEAR ::isError ($ error = $ this ->put ('AUTH ' , 'DIGEST-MD5 ' ))) {
826
842
return $ error ;
827
843
}
@@ -834,8 +850,7 @@ protected function authDigestMD5($uid, $pwd, $authz = '')
834
850
return $ error ;
835
851
}
836
852
837
- $ auth_sasl = new Auth_SASL ;
838
- $ digest = $ auth_sasl ->factory ('digest-md5 ' );
853
+ $ digest = Auth_SASL::factory ('digest-md5 ' );
839
854
$ challenge = base64_decode ($ this ->arguments [0 ]);
840
855
$ auth_str = base64_encode (
841
856
$ digest ->getResponse ($ uid , $ pwd , $ challenge , $ this ->host , "smtp " , $ authz )
@@ -871,9 +886,13 @@ protected function authDigestMD5($uid, $pwd, $authz = '')
871
886
* @return mixed Returns a PEAR_Error with an error message on any
872
887
* kind of failure, or true on success.
873
888
* @since 1.1.0
889
+ * @deprecated 1.11.0
874
890
*/
875
891
protected function authCRAMMD5 ($ uid , $ pwd , $ authz = '' )
876
892
{
893
+ trigger_error (__CLASS__ . ' ( ' . $ this ->host . '): Authentication method CRAM-MD5 ' .
894
+ ' is no longer secure and should be avoided. ' , E_USER_DEPRECATED );
895
+
877
896
if (PEAR ::isError ($ error = $ this ->put ('AUTH ' , 'CRAM-MD5 ' ))) {
878
897
return $ error ;
879
898
}
@@ -886,9 +905,8 @@ protected function authCRAMMD5($uid, $pwd, $authz = '')
886
905
return $ error ;
887
906
}
888
907
889
- $ auth_sasl = new Auth_SASL ;
890
908
$ challenge = base64_decode ($ this ->arguments [0 ]);
891
- $ cram = $ auth_sasl -> factory ('cram-md5 ' );
909
+ $ cram = Auth_SASL:: factory ('cram-md5 ' );
892
910
$ auth_str = base64_encode ($ cram ->getResponse ($ uid , $ pwd , $ challenge ));
893
911
894
912
if (PEAR ::isError ($ error = $ this ->put ($ auth_str ))) {
@@ -911,9 +929,13 @@ protected function authCRAMMD5($uid, $pwd, $authz = '')
911
929
* @return mixed Returns a PEAR_Error with an error message on any
912
930
* kind of failure, or true on success.
913
931
* @since 1.1.0
932
+ * @deprecated 1.11.0
914
933
*/
915
934
protected function authLogin ($ uid , $ pwd , $ authz = '' )
916
935
{
936
+ trigger_error (__CLASS__ . ' ( ' . $ this ->host . '): Authentication method LOGIN ' .
937
+ ' is no longer secure and should be avoided. ' , E_USER_DEPRECATED );
938
+
917
939
if (PEAR ::isError ($ error = $ this ->put ('AUTH ' , 'LOGIN ' ))) {
918
940
return $ error ;
919
941
}
@@ -1075,6 +1097,7 @@ protected function authGSSAPI($uid, $pwd, $authz = '')
1075
1097
* @param string $uid The userid to authenticate as.
1076
1098
* @param string $token The access token to authenticate with.
1077
1099
* @param string $authz The optional authorization proxy identifier.
1100
+ * @param object $conn The current object
1078
1101
*
1079
1102
* @return mixed Returns a PEAR_Error with an error message on any
1080
1103
* kind of failure, or true on success.
@@ -1129,6 +1152,159 @@ public function authXOAuth2($uid, $token, $authz, $conn)
1129
1152
return true ;
1130
1153
}
1131
1154
1155
+ /**
1156
+ * Authenticates the user using the SCRAM-SHA-1 method.
1157
+ *
1158
+ * @param string $uid The userid to authenticate as.
1159
+ * @param string $pwd The password to authenticate with.
1160
+ * @param string $authz The optional authorization proxy identifier.
1161
+ *
1162
+ * @return mixed Returns a PEAR_Error with an error message on any
1163
+ * kind of failure, or true on success.
1164
+ * @since 1.11.0
1165
+ */
1166
+ protected function authScramSHA1 ($ uid , $ pwd , $ authz = '' )
1167
+ {
1168
+ $ this ->scram_sha_hash_algorithm = 'SCRAM-SHA-1 ' ;
1169
+ return $ this ->authScramSHA ($ uid , $ pwd , $ authz );
1170
+ }
1171
+
1172
+ /**
1173
+ * Authenticates the user using the SCRAM-SHA-224 method.
1174
+ *
1175
+ * @param string $uid The userid to authenticate as.
1176
+ * @param string $pwd The password to authenticate with.
1177
+ * @param string $authz The optional authorization proxy identifier.
1178
+ *
1179
+ * @return mixed Returns a PEAR_Error with an error message on any
1180
+ * kind of failure, or true on success.
1181
+ * @since 1.11.0
1182
+ */
1183
+ protected function authScramSHA224 ($ uid , $ pwd , $ authz = '' )
1184
+ {
1185
+ $ this ->scram_sha_hash_algorithm = 'SCRAM-SHA-224 ' ;
1186
+ return $ this ->authScramSHA ($ uid , $ pwd , $ authz );
1187
+ }
1188
+
1189
+ /**
1190
+ * Authenticates the user using the SCRAM-SHA-256 method.
1191
+ *
1192
+ * @param string $uid The userid to authenticate as.
1193
+ * @param string $pwd The password to authenticate with.
1194
+ * @param string $authz The optional authorization proxy identifier.
1195
+ *
1196
+ * @return mixed Returns a PEAR_Error with an error message on any
1197
+ * kind of failure, or true on success.
1198
+ * @since 1.11.0
1199
+ */
1200
+ protected function authScramSHA256 ($ uid , $ pwd , $ authz = '' )
1201
+ {
1202
+ $ this ->scram_sha_hash_algorithm = 'SCRAM-SHA-256 ' ;
1203
+ return $ this ->authScramSHA ($ uid , $ pwd , $ authz );
1204
+ }
1205
+
1206
+ /**
1207
+ * Authenticates the user using the SCRAM-SHA-384 method.
1208
+ *
1209
+ * @param string $uid The userid to authenticate as.
1210
+ * @param string $pwd The password to authenticate with.
1211
+ * @param string $authz The optional authorization proxy identifier.
1212
+ *
1213
+ * @return mixed Returns a PEAR_Error with an error message on any
1214
+ * kind of failure, or true on success.
1215
+ * @since 1.11.0
1216
+ */
1217
+ protected function authScramSHA384 ($ uid , $ pwd , $ authz = '' )
1218
+ {
1219
+ $ this ->scram_sha_hash_algorithm = 'SCRAM-SHA-384 ' ;
1220
+ return $ this ->authScramSHA ($ uid , $ pwd , $ authz );
1221
+ }
1222
+
1223
+ /**
1224
+ * Authenticates the user using the SCRAM-SHA-512 method.
1225
+ *
1226
+ * @param string $uid The userid to authenticate as.
1227
+ * @param string $pwd The password to authenticate with.
1228
+ * @param string $authz The optional authorization proxy identifier.
1229
+ *
1230
+ * @return mixed Returns a PEAR_Error with an error message on any
1231
+ * kind of failure, or true on success.
1232
+ * @since 1.11.0
1233
+ */
1234
+ protected function authScramSHA512 ($ uid , $ pwd , $ authz = '' )
1235
+ {
1236
+ $ this ->scram_sha_hash_algorithm = 'SCRAM-SHA-512 ' ;
1237
+ return $ this ->authScramSHA ($ uid , $ pwd , $ authz );
1238
+ }
1239
+
1240
+ /**
1241
+ * Authenticates the user using the SCRAM-SHA method.
1242
+ *
1243
+ * @param string $uid The userid to authenticate as.
1244
+ * @param string $pwd The password to authenticate with.
1245
+ * @param string $authz The optional authorization proxy identifier.
1246
+ *
1247
+ * @return mixed Returns a PEAR_Error with an error message on any
1248
+ * kind of failure, or true on success.
1249
+ * @since 1.11.0
1250
+ */
1251
+ protected function authScramSHA ($ uid , $ pwd , $ authz = '' )
1252
+ {
1253
+ if (PEAR ::isError ($ error = $ this ->put ('AUTH ' , $ this ->scram_sha_hash_algorithm ))) {
1254
+ return $ error ;
1255
+ }
1256
+ /* 334: Continue authentication request */
1257
+ if (PEAR ::isError ($ error = $ this ->parseResponse (334 ))) {
1258
+ /* 503: Error: already authenticated */
1259
+ if ($ this ->code === 503 ) {
1260
+ return true ;
1261
+ }
1262
+ return $ error ;
1263
+ }
1264
+
1265
+ $ cram = Auth_SASL::factory ($ this ->scram_sha_hash_algorithm );
1266
+ $ auth_str = base64_encode ($ cram ->getResponse ($ uid , $ pwd ));
1267
+
1268
+ /* Step 1: Send first authentication request */
1269
+ if (PEAR ::isError ($ error = $ this ->put ($ auth_str ))) {
1270
+ return $ error ;
1271
+ }
1272
+
1273
+ /* 334: Continue authentication request with password salt */
1274
+ if (PEAR ::isError ($ error = $ this ->parseResponse (334 ))) {
1275
+ return $ error ;
1276
+ }
1277
+
1278
+ $ challenge = base64_decode ($ this ->arguments [0 ]);
1279
+ $ auth_str = base64_encode ($ cram ->getResponse ($ uid , $ pwd , $ challenge ));
1280
+
1281
+ /* Step 2: Send salted authentication request */
1282
+ if (PEAR ::isError ($ error = $ this ->put ($ auth_str ))) {
1283
+ return $ error ;
1284
+ }
1285
+
1286
+ /* 334: Continue authentication request with password salt */
1287
+ if (PEAR ::isError ($ error = $ this ->parseResponse (334 ))) {
1288
+ return $ error ;
1289
+ }
1290
+
1291
+ /* Verify server signature */
1292
+ $ verification = $ cram ->processOutcome (base64_decode ($ this ->arguments [0 ]));
1293
+ if ($ verification == false ) {
1294
+ return PEAR ::raiseError ("SCRAM Server verification on step 3 not successful " );
1295
+ }
1296
+
1297
+ /* Step 3: Send a request to acknowledge verification */
1298
+ if (PEAR ::isError ($ error = $ this ->put ("NOOP " ))) {
1299
+ return $ error ;
1300
+ }
1301
+
1302
+ /* 235: Authentication successful */
1303
+ if (PEAR ::isError ($ error = $ this ->parseResponse (235 ))) {
1304
+ return $ error ;
1305
+ }
1306
+ }
1307
+
1132
1308
/**
1133
1309
* Send the HELO command.
1134
1310
*
0 commit comments