U BB`LQ@sddlZddlZddlmZmZddlmZddlmZddl m Z ddl m Z m Z mZmZmZmZmZmZmZmZmZmZmZddlmZddlmZdd lmZmZm Z m!Z!m"Z"m#Z#m$Z$eGd d d eZ%eGd d d eZ&ddZ'Gddde(Z)dZ*dZ+ddZ,GdddZ-dPddZ.ddZ/GdddZ0ddZ1Gd d!d!Z2d"d#Z3d$d%Z4d&d'Z5d(d)Z6d*d+Z7d,d-Z8d.d/Z9d0d1Z:d2d3Z;d4d5Zd:d;Z?dZBdeZdZdddZddZddZdd Zd d Zd d ZdS) ScramClientNcst|ttfstdtdd|D}fdd|D}t|dkrRtdt|tddd }|j |j |_ |_ |j |_ |j rdkrtd ndk rtd |dkrt n||_||_||_|_d|_dS) NzFThe 'mechanisms' parameter must be a list or tuple of mechanism names.cSsg|] }t|qSr*)rQ.0mr*r*r+ sz(ScramClient.__init__..cs&g|]}dk sdkr|js|qSr5)rYryrgr*r+r|s rz-There are no suitable mechanisms in the list.r[)keyzKThe channel_binding parameter can't be None if channel binding is required.zNThe channel_binding parameter must be None if channel binding is not required.)rqlistrrr1rwrs ExceptionsortedrrXrYr2Zmechanism_name _make_noncec_nonceusernamer_rgstage)r9Z mechanismsrr_rgrZmechsZmechr*r}r+r7s8  zScramClient.__init__cCstt|j|||_dSr5)r4rrr9r3r*r*r+ _set_stageszScramClient._set_stagecCs(|tjt|j|j|j\|_}|Sr5)rrr&_get_client_firstrrrgclient_first_bare)r9 client_firstr*r*r+r&s  zScramClient.get_client_firstcCs:|tj||_t||j|j|j\|_|_ |_ |_ dSr5) rrr' server_first_set_server_firstrrrg auth_messagenoncer] iterationsr9r:r*r*r+r's zScramClient.set_server_firstcCs8|tjt|j|j|j|j|j|j |j \|_ }|Sr5) rrr(_get_client_finalrXr_r]rrrrgserver_signature)r9Zcfinalr*r*r+r(s  zScramClient.get_client_finalcCs|tjt||jdSr5)rrr)_set_server_finalrrr*r*r+r)s zScramClient.set_server_final)NN) r#r$r%r7rr&r'r(r)r*r*r*r+rxs 'rxcstfdd}|S)Nc sXz|f||WStk rR}z"|jdk r>|j|_tj|_|W5d}~XYnXdSr5)r1r8errorr,r/r)r9argskwdsefr*r+wrappers zset_error..wrapperr)rrr*rr+ set_errorsrc@sNeZdZdddZddZeddZedd Zed d Zed d Z dS)riNcCsl||_t||jr&|dkr6tdn|dk r6td||_|dkrJtn||_||_d|_d|_ d|_ dS)NzMThe mechanism requires channel binding, and so channel_binding can't be None.zTThe mechanism does not support channel binding, and so channel_binding must be None.) r{rwrYr1rgrrhrjrrr)r9r\rjrgrhr*r*r+r7s"zScramServer.__init__cCstt|j|||_dSr5)r4r,rrr*r*r+rszScramServer._set_stagecCsP|tjt||j|j\|_|_|_| |j\}|_ |_ |_ t ||_dSr5)rr,r-_set_client_firstrhrgruserrrjr`rarprr])r9rr]r*r*r+r-!s zScramServer.set_client_firstcCs0|tjt|j|j|j|j|j\|_ }|Sr5) rr,r._get_server_firstrr]rprrgr)r9rr*r*r+r.*s  zScramServer.get_server_firstcCs4|tjt|jj||j|j|j|j |j |_ dSr5) rr,r/_set_client_finalr{rXrhr`rarrgr)r9 client_finalr*r*r+r/2s zScramServer.set_client_finalcCs|tjt|j|jSr5)rr,r0_get_server_finalrr)r9r*r*r+r09s zScramServer.get_server_final)NN) r#r$r%r7rrr-r.r/r0r*r*r*r+ris    ricCsttddS)N-r=)strrreplacer*r*r*r+r?srcCs*tt|}||d|d|f}d|S)Nc=r=,)r_make_cbind_inputjoin)rrr cbind_data cbind_inputmsgr*r*r+_make_auth_messageCs rcCst|tt|||Sr5)rrsaslprep)rXr_r]rr*r*r+roIsrocCs,t||d}t||}t||d}|||fS)Ns Client Keys Server Key)rr)rXrd client_keyr`rar*r*r+rcMs   rccCs:t|||}t|t|}t||}||kr6tdtdS)NzThe client keys don't match.)rrrrr1SERVER_ERROR_INVALID_PROOF)rXr`auth_msgproofclient_signaturerr~r*r*r+_check_client_keyUs  rcCs$|dkr dS|\}}d|dSdS)Nzn,,p=z,,r*)rgrvrer*r*r+_make_gs2_header_srcCs.t|d}|dkr|S|\}}||SdS)Nascii)rencode)rg gs2_headerrerr*r*r+rgs rcCstdd|dDS)Ncss.|]&}t|dkr|d|ddfVqdS)rrr N)rs)rzrr*r*r+ qs z!_parse_message..r)dictsplit)rr*r*r+_parse_messagepsrc Csnz t|}Wn2tk r>}zt|jdtW5d}~XYnXdd|d|f}t|}|||fS)Nrrzn=r)rr1r&SERVER_ERROR_INVALID_USERNAME_ENCODINGrr)rrrgurZbarerr*r*r+rts rcCs|d}|d|d}|d|d}|d}|d}|dkrX|dk rtdtn|dkrt|dk rtdtnd|dkr|dkrtd t|\}} |d d } | |krtd | d |dtntd|dt||dd} t| } | d} | |}| d}||| fS)Nrrryz}Recieved GS2 flag 'y' which indicates that the client doesn't think the server supports channel binding, but in fact it does.nzkReceived GS2 flag 'n' which indicates that the client doesn't require channel binding, but the server does.pzhReceived GS2 flag 'p' which indicates that the client requires channel binding, but the server does not.=rzReceived channel binding name z3 but this server supports the channel binding name rUzReceived GS2 flag z which isn't recognized.r)indexrr10SERVER_ERROR_SERVER_DOES_SUPPORT_CHANNEL_BINDING*SERVER_ERROR_CHANNEL_BINDING_NOT_SUPPORTED-SERVER_ERROR_UNSUPPORTED_CHANNEL_BINDING_TYPESERVER_ERROR_OTHER_ERRORr)rrhrgZ first_commaZ second_commarZgs2_cbind_flagZgs2_charrvreZcb_namerrrrrr*r*r+rsP  rcCs8dd|d|d|f}t||||}||fS)Nrrzs=zi=)rr)rr]rrrgZsfirstrr*r*r+rs"rc Cslt|}d|kr"td|d|d}|d}t|d}||sRtdtt||||}||||fS)NrThe server returned the error: rsrpzClient nonce doesn't match.)rr1int startswithrr) rrrrgrrr]rrr*r*r+rs$  rcCst|}t||||}t||\} } } t|} t|| | } t| | }t|| | }t|}dt|d|dt|g}t|d|fS)Nrrrr) rrorcrrrrrr)rXr_Zsalt_strrr auth_msg_strrr]rdrr`rarrZ client_proofrrrr*r*r+rs       rzinvalid-encodingzextensions-not-supportedz invalid-proofzchannel-bindings-dont-matchz#server-does-support-channel-bindingz'server does not support channel bindingzchannel-binding-not-supportedz unsupported-channel-binding-typez unknown-userzinvalid-username-encodingz no-resourcesz other-errorc Csxt|}t|}|d} |d} |d} t| t|ksBtdt| |sVtdtt|||| t |||} t | S)Nrrcz!The channel bindings don't match.zServer nonce doesn't match.) rrrrr1(SERVER_ERROR_CHANNEL_BINDINGS_DONT_MATCHendswithrrrr) rXrrhr`rarrrrrrrgsigr*r*r+rs$  rcCs|dkrd|Sd|S)Nzv=ze=r*)rrr*r*r+r srcCs<t|}d|kr"td|d||dkr8tdtdS)Nrrvz#The server signature doesn't match.)rr1r)r:rrr*r*r+r s rc Csddd|D}td|}|s(dSt}||drT||dsNtdtt}n|}|D]}t|rptdt |rtd t d ft d ft d ft d ftdftdftdftdftdf|dff D]\}}||rt|tqq\|S)Nr=css&|]}t|st|rdn|VqdS)r>N)r r )rzrr*r*r+rszsaslprep..NFKCrrzmalformed bidi sequencez$failed to strip B.1 in mapping stagez(failed to replace C.1.2 in mapping stagez unassigned code points forbiddenzcontrol characters forbiddenz private use characters forbiddenznon-char code points forbiddenzsurrogate codes forbiddenznon-plaintext chars forbiddenznon-canonical chars forbiddenz,display-modifying/deprecated chars forbiddenztagged characters forbiddenzforbidden bidi character)r unicodedata normalizerr1SERVER_ERROR_INVALID_ENCODINGrr AssertionErrorr rr r r rrrrr)sourcedataZ is_ral_charZis_forbidden_bidi_charrrrr*r*r+rs@      r)N)PrMrenumrr functoolsroperatorrosr stringpreprr r r r r rrrrrrruuidrZasn1crypto.x509rZ scramp.utilsrrrrrrrrr,r4rr1rVrtrPrQr^rwrxrrirrrorcrrrrrrrrrrZ%SERVER_ERROR_EXTENSIONS_NOT_SUPPORTEDrrrZ4SERVER_ERROR_SERVER_DOES_NOT_SUPPORT_CHANNEL_BINDINGrrZSERVER_ERROR_UNKNOWN_USERrZSERVER_ERROR_NO_RESOURCESrrrrrr*r*r*r+sr   <  $  & F ;   3