Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file auth.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117(* XXX(dinosaure): RFC 4616, mechanism consists of a single message, a string of
UTF-8 encoded Unicode characters. TODO: [SASLprep][RFC4013]/[hannesm/precis] *)moduleClient=structtypemechanism=|PLAINletpp_mechanismppf=function|PLAIN->Fmt.stringppf"PLAIN"letmechanism_to_string=Fmt.to_to_stringpp_mechanismtypeColombe.Rfc1869.error+=|Unsupported_mechanismofmechanism(* 504 *)|Authentication_rejected(* 501 *)|Weak_mechanismofmechanism(* 534 *)|Authentication_failed(* 535 *)|Line_too_long(* 500 *)|Encryption_required(* 538 *)|Invalid_statetypeerror=Colombe.Rfc1869.errorletpp_errorppf=function|Unsupported_mechanismm->Fmt.pfppf"(Unsupported_mechanism %a)"pp_mechanismm|Authentication_rejected->Fmt.stringppf"Authentication_rejected"|Authentication_failed->Fmt.stringppf"Authentication_failed"|Weak_mechanismm->Fmt.pfppf"(Weak_mechanism %a)"pp_mechanismm|Line_too_long->Fmt.stringppf"Line_too_long"|Encryption_required->Fmt.stringppf"Encryption_required"|Invalid_state->Fmt.stringppf"Invalid_state"|err->Colombe.Rfc1869.pp_errorppferrtypet={mechanism:mechanism;q:[`q0|`q1_plainofstringoption|`authenticated];username:string;password:string}letehlotargs=letms=Astring.String.cuts~sep:" "argsinifList.exists((=)(mechanism_to_stringt.mechanism))msthenOktelseError(Unsupported_mechanismt.mechanism)letencodet=matcht.q,t.mechanismwith|`q0,PLAIN->Colombe.Rfc1869.Request{verb="AUTH";args=["PLAIN"]}|`q1_plainid,PLAIN->letcombined=matchidwith|Someid->Fmt.strf"%s\000%s\000%s"idt.usernamet.password|None->Fmt.strf"\000%s\000%s"t.usernamet.passwordin(* lol *)letbuf=Base64.encode_exn~pad:truecombinedinColombe.Rfc1869.Payload{buf=Bytes.unsafe_of_string(buf^"\r\n");off=0;len=String.lengthbuf+2}|`authenticated,PLAIN->Fmt.failwith"Impossible to encode something where we are already authenticated"lethandlet=tletactiont=matcht.qwith|`q0->Some(Colombe.Rfc1869.Recv_code334)|`q1_plain_->Some(Colombe.Rfc1869.Recv_code235)|`authenticated->Noneletdecoderespt=matcht.q,respwith|`q0,Colombe.Rfc1869.Response{code=504;_}->Error(Unsupported_mechanismt.mechanism)|`q0,Colombe.Rfc1869.Response{code=538;_}->ErrorEncryption_required|`q0,Colombe.Rfc1869.Response{code=534;_}->assert(t.mechanism=PLAIN);Error(Weak_mechanismt.mechanism)|`q0,Colombe.Rfc1869.Response{code=334;txts;}->letid=matchtxtswith|[]->None|x::_->Some(Base64.decode_exnx)in(* XXX(dinosaure): should alert when r <> []? *)Ok{twithq=`q1_plainid}|`q1_plain_,Colombe.Rfc1869.Response{code=235;_}->Ok{twithq=`authenticated}|`q1_plain_,Colombe.Rfc1869.Response{code=500;_}->ErrorLine_too_long|`q1_plain_,Colombe.Rfc1869.Response{code=501;_}->ErrorAuthentication_rejected|`q1_plain_,Colombe.Rfc1869.Response{code=535;_}->ErrorAuthentication_failed|_->ErrorInvalid_stateletis_authenticatedt=t.q=`authenticatedletmail_from_t_mail_from=[](* TODO: handle [AUTH=] parameter *)letrcpt_to_t_rcpt_to=[]endtypeauthenticator=Client.ttypemechanism=Client.mechanismletpp_mechanismppfClient.PLAIN=Fmt.stringppf"PLAIN"letdescription:Colombe.Rfc1869.description={name="Authentication";elho="AUTH";verb=["AUTH"]}letplain=Client.PLAINletmake?(mechanism=Client.PLAIN)~usernamepassword={Client.mechanism;q=`q0;username;password}letis_authenticated=Client.is_authenticatedletextension=Colombe.Rfc1869.inj(moduleClient)moduleExtension=(valextension)letinjv=Extension.Tv