@@ -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. */
@@ -426,7 +438,7 @@ public function command($command, $valid)
426
438
*/
427
439
public function getResponse ()
428
440
{
429
- return array ($ this ->code , join ("\n" , $ this ->arguments ));
441
+ return array ($ this ->code , implode ("\n" , $ this ->arguments ));
430
442
}
431
443
432
444
/**
@@ -1021,6 +1033,7 @@ protected function authGSSAPI($uid, $pwd, $authz = '')
1021
1033
* @param string $uid The userid to authenticate as.
1022
1034
* @param string $token The access token to authenticate with.
1023
1035
* @param string $authz The optional authorization proxy identifier.
1036
+ * @param object $conn The current object
1024
1037
*
1025
1038
* @return mixed Returns a PEAR_Error with an error message on any
1026
1039
* kind of failure, or true on success.
@@ -1075,6 +1088,160 @@ public function authXOAuth2($uid, $token, $authz, $conn)
1075
1088
return true ;
1076
1089
}
1077
1090
1091
+ /**
1092
+ * Authenticates the user using the SCRAM-SHA-1 method.
1093
+ *
1094
+ * @param string $uid The userid to authenticate as.
1095
+ * @param string $pwd The password to authenticate with.
1096
+ * @param string $authz The optional authorization proxy identifier.
1097
+ *
1098
+ * @return mixed Returns a PEAR_Error with an error message on any
1099
+ * kind of failure, or true on success.
1100
+ * @since 1.11.0
1101
+ */
1102
+ protected function authScramSHA1 ($ uid , $ pwd , $ authz = '' )
1103
+ {
1104
+ $ this ->scram_sha_hash_algorithm = 'SCRAM-SHA-1 ' ;
1105
+ return $ this ->authScramSHA ($ uid , $ pwd , $ authz );
1106
+ }
1107
+
1108
+ /**
1109
+ * Authenticates the user using the SCRAM-SHA-224 method.
1110
+ *
1111
+ * @param string $uid The userid to authenticate as.
1112
+ * @param string $pwd The password to authenticate with.
1113
+ * @param string $authz The optional authorization proxy identifier.
1114
+ *
1115
+ * @return mixed Returns a PEAR_Error with an error message on any
1116
+ * kind of failure, or true on success.
1117
+ * @since 1.11.0
1118
+ */
1119
+ protected function authScramSHA224 ($ uid , $ pwd , $ authz = '' )
1120
+ {
1121
+ $ this ->scram_sha_hash_algorithm = 'SCRAM-SHA-224 ' ;
1122
+ return $ this ->authScramSHA ($ uid , $ pwd , $ authz );
1123
+ }
1124
+
1125
+ /**
1126
+ * Authenticates the user using the SCRAM-SHA-256 method.
1127
+ *
1128
+ * @param string $uid The userid to authenticate as.
1129
+ * @param string $pwd The password to authenticate with.
1130
+ * @param string $authz The optional authorization proxy identifier.
1131
+ *
1132
+ * @return mixed Returns a PEAR_Error with an error message on any
1133
+ * kind of failure, or true on success.
1134
+ * @since 1.11.0
1135
+ */
1136
+ protected function authScramSHA256 ($ uid , $ pwd , $ authz = '' )
1137
+ {
1138
+ $ this ->scram_sha_hash_algorithm = 'SCRAM-SHA-256 ' ;
1139
+ return $ this ->authScramSHA ($ uid , $ pwd , $ authz );
1140
+ }
1141
+
1142
+ /**
1143
+ * Authenticates the user using the SCRAM-SHA-384 method.
1144
+ *
1145
+ * @param string $uid The userid to authenticate as.
1146
+ * @param string $pwd The password to authenticate with.
1147
+ * @param string $authz The optional authorization proxy identifier.
1148
+ *
1149
+ * @return mixed Returns a PEAR_Error with an error message on any
1150
+ * kind of failure, or true on success.
1151
+ * @since 1.11.0
1152
+ */
1153
+ protected function authScramSHA384 ($ uid , $ pwd , $ authz = '' )
1154
+ {
1155
+ $ this ->scram_sha_hash_algorithm = 'SCRAM-SHA-384 ' ;
1156
+ return $ this ->authScramSHA ($ uid , $ pwd , $ authz );
1157
+ }
1158
+
1159
+ /**
1160
+ * Authenticates the user using the SCRAM-SHA-512 method.
1161
+ *
1162
+ * @param string $uid The userid to authenticate as.
1163
+ * @param string $pwd The password to authenticate with.
1164
+ * @param string $authz The optional authorization proxy identifier.
1165
+ *
1166
+ * @return mixed Returns a PEAR_Error with an error message on any
1167
+ * kind of failure, or true on success.
1168
+ * @since 1.11.0
1169
+ */
1170
+ protected function authScramSHA512 ($ uid , $ pwd , $ authz = '' )
1171
+ {
1172
+ $ this ->scram_sha_hash_algorithm = 'SCRAM-SHA-512 ' ;
1173
+ return $ this ->authScramSHA ($ uid , $ pwd , $ authz );
1174
+ }
1175
+
1176
+ /**
1177
+ * Authenticates the user using the SCRAM-SHA method.
1178
+ *
1179
+ * @param string $uid The userid to authenticate as.
1180
+ * @param string $pwd The password to authenticate with.
1181
+ * @param string $authz The optional authorization proxy identifier.
1182
+ *
1183
+ * @return mixed Returns a PEAR_Error with an error message on any
1184
+ * kind of failure, or true on success.
1185
+ * @since 1.11.0
1186
+ */
1187
+ protected function authScramSHA ($ uid , $ pwd , $ authz = '' )
1188
+ {
1189
+ if (PEAR ::isError ($ error = $ this ->put ('AUTH ' , $ this ->scram_sha_hash_algorithm ))) {
1190
+ return $ error ;
1191
+ }
1192
+ /* 334: Continue authentication request */
1193
+ if (PEAR ::isError ($ error = $ this ->parseResponse (334 ))) {
1194
+ /* 503: Error: already authenticated */
1195
+ if ($ this ->code === 503 ) {
1196
+ return true ;
1197
+ }
1198
+ return $ error ;
1199
+ }
1200
+
1201
+ $ auth_sasl = new Auth_SASL ;
1202
+ $ cram = $ auth_sasl ->factory ($ this ->scram_sha_hash_algorithm );
1203
+ $ auth_str = base64_encode ($ cram ->getResponse ($ uid , $ pwd ));
1204
+
1205
+ /* Step 1: Send first authentication request */
1206
+ if (PEAR ::isError ($ error = $ this ->put ($ auth_str ))) {
1207
+ return $ error ;
1208
+ }
1209
+
1210
+ /* 334: Continue authentication request with password salt */
1211
+ if (PEAR ::isError ($ error = $ this ->parseResponse (334 ))) {
1212
+ return $ error ;
1213
+ }
1214
+
1215
+ $ challenge = base64_decode ($ this ->arguments [0 ]);
1216
+ $ auth_str = base64_encode ($ cram ->getResponse ($ uid , $ pwd , $ challenge ));
1217
+
1218
+ /* Step 2: Send salted authentication request */
1219
+ if (PEAR ::isError ($ error = $ this ->put ($ auth_str ))) {
1220
+ return $ error ;
1221
+ }
1222
+
1223
+ /* 334: Continue authentication request with password salt */
1224
+ if (PEAR ::isError ($ error = $ this ->parseResponse (334 ))) {
1225
+ return $ error ;
1226
+ }
1227
+
1228
+ /* Verify server signature */
1229
+ $ verification = $ cram ->processOutcome (base64_decode ($ this ->arguments [0 ]));
1230
+ if ($ verification == false ) {
1231
+ return PEAR ::raiseError ("SCRAM Server verification on step 3 not successful " );
1232
+ }
1233
+
1234
+ /* Step 3: Send a request to acknowledge verification */
1235
+ if (PEAR ::isError ($ error = $ this ->put ("NOOP " ))) {
1236
+ return $ error ;
1237
+ }
1238
+
1239
+ /* 235: Authentication successful */
1240
+ if (PEAR ::isError ($ error = $ this ->parseResponse (235 ))) {
1241
+ return $ error ;
1242
+ }
1243
+ }
1244
+
1078
1245
/**
1079
1246
* Send the HELO command.
1080
1247
*
0 commit comments