@@ -16,9 +16,12 @@ use error::Result;
1616use rustc_serialize:: base64:: { self , FromBase64 , ToBase64 } ;
1717use textnonce:: TextNonce ;
1818
19- const B64_CONFIG : base64:: Config = base64:: Config { char_set : base64:: CharacterSet :: Standard ,
20- newline : base64:: Newline :: LF ,
21- pad : true , line_length : None } ;
19+ const B64_CONFIG : base64:: Config = base64:: Config {
20+ char_set : base64:: CharacterSet :: Standard ,
21+ newline : base64:: Newline :: LF ,
22+ pad : true ,
23+ line_length : None ,
24+ } ;
2225
2326/// Handles SCRAM-SHA-1 authentication logic.
2427pub struct Authenticator {
@@ -57,7 +60,7 @@ impl Authenticator {
5760 fn start ( & self , user : & str ) -> Result < InitialData > {
5861 let text_nonce = match TextNonce :: sized ( 64 ) {
5962 Ok ( text_nonce) => text_nonce,
60- Err ( string) => return Err ( DefaultError ( string) )
63+ Err ( string) => return Err ( DefaultError ( string) ) ,
6164 } ;
6265
6366 let nonce = format ! ( "{}" , text_nonce) ;
@@ -76,51 +79,59 @@ impl Authenticator {
7679
7780 let data = match doc. get ( "payload" ) {
7881 Some ( & Binary ( _, ref payload) ) => payload. to_owned ( ) ,
79- _ => return Err ( ResponseError ( "Invalid payload returned" . to_owned ( ) ) )
82+ _ => return Err ( ResponseError ( String :: from ( "Invalid payload returned" ) ) ) ,
8083 } ;
8184
8285 let id = match doc. get ( "conversationId" ) {
8386 Some ( bson) => bson. clone ( ) ,
84- None => return Err ( ResponseError ( "No conversationId returned" . to_owned ( ) ) )
87+ None => return Err ( ResponseError ( String :: from ( "No conversationId returned" ) ) ) ,
8588 } ;
8689
8790 let response = match String :: from_utf8 ( data) {
8891 Ok ( string) => string,
89- Err ( _) => return Err ( ResponseError ( "Invalid UTF-8 payload returned" . to_owned ( ) ) )
92+ Err ( _) => return Err ( ResponseError ( String :: from ( "Invalid UTF-8 payload returned" ) ) ) ,
9093 } ;
9194
92- Ok ( InitialData { message : message, response : response, nonce : nonce,
93- conversation_id : id } )
95+ Ok ( InitialData {
96+ message : message,
97+ response : response,
98+ nonce : nonce,
99+ conversation_id : id,
100+ } )
94101 }
95102
96103 fn next ( & self , password : String , initial_data : InitialData ) -> Result < AuthData > {
97104 // Parse out rnonce, salt, and iteration count
98- let ( rnonce_opt, salt_opt, i_opt) = scan_fmt ! ( & initial_data. response[ ..] , "r={},s={},i={}" , String , String , u32 ) ;
105+ let ( rnonce_opt, salt_opt, i_opt) = scan_fmt ! ( & initial_data. response[ ..] ,
106+ "r={},s={},i={}" ,
107+ String ,
108+ String ,
109+ u32 ) ;
99110
100111 let rnonce_b64 = match rnonce_opt {
101112 Some ( val) => val,
102- None => return Err ( ResponseError ( "Invalid rnonce returned" . to_owned ( ) ) )
113+ None => return Err ( ResponseError ( String :: from ( "Invalid rnonce returned" ) ) ) ,
103114 } ;
104115
105116 // Validate rnonce to make sure server isn't malicious
106117 if !rnonce_b64. starts_with ( & initial_data. nonce [ ..] ) {
107- return Err ( MaliciousServerError ( MaliciousServerErrorType :: InvalidRnonce ) )
118+ return Err ( MaliciousServerError ( MaliciousServerErrorType :: InvalidRnonce ) ) ;
108119 }
109120
110121 let salt_b64 = match salt_opt {
111122 Some ( val) => val,
112- None => return Err ( ResponseError ( "Invalid salt returned" . to_owned ( ) ) )
123+ None => return Err ( ResponseError ( String :: from ( "Invalid salt returned" ) ) ) ,
113124 } ;
114125
115126 let salt = match salt_b64. from_base64 ( ) {
116127 Ok ( val) => val,
117- Err ( _) => return Err ( ResponseError ( "Invalid base64 salt returned" . to_owned ( ) ) )
128+ Err ( _) => return Err ( ResponseError ( String :: from ( "Invalid base64 salt returned" ) ) ) ,
118129 } ;
119130
120131
121132 let i = match i_opt {
122133 Some ( val) => val,
123- None => return Err ( ResponseError ( "Invalid iteration count returned" . to_owned ( ) ) )
134+ None => return Err ( ResponseError ( String :: from ( "Invalid iteration count returned" ) ) ) ,
124135 } ;
125136
126137 // Hash password
@@ -130,24 +141,27 @@ impl Authenticator {
130141
131142 // Salt password
132143 let mut hmac = Hmac :: new ( Sha1 :: new ( ) , hashed_password. as_bytes ( ) ) ;
133- let mut salted_password : Vec < _ > = ( 0 ..hmac. output_bytes ( ) ) . map ( |_| 0 ) . collect ( ) ;
144+ let mut salted_password: Vec < _ > = ( 0 ..hmac. output_bytes ( ) ) . map ( |_| 0 ) . collect ( ) ;
134145 pbkdf2:: pbkdf2 ( & mut hmac, & salt[ ..] , i, & mut salted_password) ;
135146
136147 // Compute client key
137148 let mut client_key_hmac = Hmac :: new ( Sha1 :: new ( ) , & salted_password[ ..] ) ;
138- let client_key_bytes = "Client Key" . as_bytes ( ) ;
149+ let client_key_bytes = b "Client Key";
139150 client_key_hmac. input ( client_key_bytes) ;
140151 let client_key = client_key_hmac. result ( ) . code ( ) . to_owned ( ) ;
141152
142153 // Hash into stored key
143154 let mut stored_key_sha1 = Sha1 :: new ( ) ;
144155 stored_key_sha1. input ( & client_key[ ..] ) ;
145- let mut stored_key : Vec < _ > = ( 0 ..stored_key_sha1. output_bytes ( ) ) . map ( |_| 0 ) . collect ( ) ;
156+ let mut stored_key: Vec < _ > = ( 0 ..stored_key_sha1. output_bytes ( ) ) . map ( |_| 0 ) . collect ( ) ;
146157 stored_key_sha1. result ( & mut stored_key) ;
147158
148159 // Create auth message
149160 let without_proof = format ! ( "c=biws,r={}" , rnonce_b64) ;
150- let auth_message = format ! ( "{},{},{}" , initial_data. message, initial_data. response, without_proof) ;
161+ let auth_message = format ! ( "{},{},{}" ,
162+ initial_data. message,
163+ initial_data. response,
164+ without_proof) ;
151165
152166 // Compute client signature
153167 let mut client_signature_hmac = Hmac :: new ( Sha1 :: new ( ) , & stored_key[ ..] ) ;
@@ -156,7 +170,8 @@ impl Authenticator {
156170
157171 // Sanity check
158172 if client_key. len ( ) != client_signature. len ( ) {
159- return Err ( DefaultError ( "Generated client key and/or client signature is invalid" . to_owned ( ) ) ) ;
173+ return Err ( DefaultError ( String :: from ( "Generated client key and/or client signature \
174+ is invalid") ) ) ;
160175 }
161176
162177 // Compute proof by xor'ing key and signature
@@ -178,8 +193,11 @@ impl Authenticator {
178193
179194 let response = try!( self . db . command ( next_doc, Suppressed , None ) ) ;
180195
181- Ok ( AuthData { salted_password : salted_password, message : auth_message,
182- response : response } )
196+ Ok ( AuthData {
197+ salted_password : salted_password,
198+ message : auth_message,
199+ response : response,
200+ } )
183201 }
184202
185203 fn finish ( & self , conversation_id : Bson , auth_data : AuthData ) -> Result < ( ) > {
@@ -191,7 +209,7 @@ impl Authenticator {
191209
192210 // Compute server key
193211 let mut server_key_hmac = Hmac :: new ( Sha1 :: new ( ) , & auth_data. salted_password [ ..] ) ;
194- let server_key_bytes = "Server Key" . as_bytes ( ) ;
212+ let server_key_bytes = b "Server Key";
195213 server_key_hmac. input ( server_key_bytes) ;
196214 let server_key = server_key_hmac. result ( ) . code ( ) . to_owned ( ) ;
197215
@@ -207,25 +225,29 @@ impl Authenticator {
207225 if let Some ( & Binary ( _, ref payload) ) = doc. get ( "payload" ) {
208226 let payload_str = match String :: from_utf8 ( payload. to_owned ( ) ) {
209227 Ok ( string) => string,
210- Err ( _) => return Err ( ResponseError ( "Invalid UTF-8 payload returned" . to_owned ( ) ) )
228+ Err ( _) => {
229+ return Err ( ResponseError ( String :: from ( "Invalid UTF-8 payload returned" ) ) )
230+ }
211231 } ;
212232
213233 // Check that the signature exists
214234 let verifier = match scan_fmt ! ( & payload_str[ ..] , "v={}" , String ) {
215235 Some ( string) => string,
216- None => return Err ( MaliciousServerError ( MaliciousServerErrorType :: NoServerSignature ) ) ,
236+ None => return Err (
237+ MaliciousServerError ( MaliciousServerErrorType :: NoServerSignature ) ) ,
217238 } ;
218239
219240 // Check that the signature is valid
220241 if verifier. ne ( & server_signature. to_base64 ( B64_CONFIG ) [ ..] ) {
221- return Err ( MaliciousServerError ( MaliciousServerErrorType :: InvalidServerSignature ) ) ;
242+ return Err (
243+ MaliciousServerError ( MaliciousServerErrorType :: InvalidServerSignature ) ) ;
222244 }
223245 }
224246
225247 doc = try!( self . db . command ( final_doc. clone ( ) , Suppressed , None ) ) ;
226248
227249 if let Some ( & Bson :: Boolean ( true ) ) = doc. get ( "done" ) {
228- return Ok ( ( ) )
250+ return Ok ( ( ) ) ;
229251 }
230252 }
231253 }
0 commit comments