11package com .rabbitmq .client .impl ;
22
3- import com .rabbitmq .client .AMQP ;
43import com .rabbitmq .client .AuthMechanism ;
54import com .rabbitmq .client .ConnectionFactory ;
6- import com .rabbitmq .client .ShutdownSignalException ;
75
8- import java .io .IOException ;
6+ import java .io .UnsupportedEncodingException ;
97import java .security .MessageDigest ;
108import java .security .NoSuchAlgorithmException ;
119import java .util .Arrays ;
@@ -25,39 +23,40 @@ This is only somewhat improved security over PLAIN (if you can
2523*/
2624
2725public class ScramMD5Mechanism implements AuthMechanism {
28- public AMQP .Connection .Tune doLogin (AMQChannel channel ,
29- ConnectionFactory factory ) throws IOException {
30- try {
31- LongString resp1 = LongStringHelper .asLongString (factory .getUsername ());
32- AMQImpl .Connection .StartOk startOk =
33- new AMQImpl .Connection .StartOk (factory .getClientProperties (), getName (),
34- resp1 , "en_US" );
35- AMQP .Connection .Secure secure =
36- (AMQP .Connection .Secure ) channel .rpc (startOk ).getMethod ();
37- byte [] challenge = secure .getChallenge ().getBytes ();
38- byte [] salt1 = Arrays .copyOfRange (challenge , 0 , 4 );
39- byte [] salt2 = Arrays .copyOfRange (challenge , 4 , 8 );
40-
41- MessageDigest digest1 = MessageDigest .getInstance ("MD5" );
42- MessageDigest digest2 = MessageDigest .getInstance ("MD5" );
43- byte [] d1 = digest1 .digest (concat (salt1 , factory .getPassword ().getBytes ("utf-8" )));
44- byte [] d2 = digest2 .digest (concat (salt2 , d1 ));
26+ public LongString handleChallenge (int round , LongString challengeStr ,
27+ ConnectionFactory factory ) {
28+ if (round == 0 ) {
29+ return LongStringHelper .asLongString (factory .getUsername ());
30+ } else {
31+ try {
32+ byte [] challenge = challengeStr .getBytes ();
33+ byte [] salt1 = Arrays .copyOfRange (challenge , 0 , 4 );
34+ byte [] salt2 = Arrays .copyOfRange (challenge , 4 , 8 );
4535
46- AMQImpl . Connection . SecureOk secureOk =
47- new AMQImpl . Connection . SecureOk ( LongStringHelper . asLongString ( d2 ));
36+ byte [] pw = factory . getPassword (). getBytes ( "utf-8" );
37+ byte [] d = digest ( salt2 , digest ( salt1 , pw ));
4838
49- return (AMQP .Connection .Tune ) channel .rpc (secureOk ).getMethod ();
50- } catch (NoSuchAlgorithmException e ) {
51- throw new RuntimeException (e );
52- } catch (ShutdownSignalException e ) {
53- throw AMQChannel .wrap (e , "Possibly caused by authentication failure" );
39+ return LongStringHelper .asLongString (d );
40+ } catch (UnsupportedEncodingException e ) {
41+ throw new RuntimeException (e );
42+ }
5443 }
5544 }
5645
5746 public String getName () {
5847 return "RABBIT-SCRAM-MD5" ;
5948 }
6049
50+ private static byte [] digest (byte [] arr1 , byte [] arr2 ) {
51+ try {
52+ MessageDigest digest = MessageDigest .getInstance ("MD5" );
53+ return digest .digest (concat (arr1 , arr2 ));
54+
55+ } catch (NoSuchAlgorithmException e ) {
56+ throw new RuntimeException (e );
57+ }
58+ }
59+
6160 private static byte [] concat (byte [] first , byte [] second ) {
6261 byte [] result = Arrays .copyOf (first , first .length + second .length );
6362 System .arraycopy (second , 0 , result , first .length , second .length );
0 commit comments