123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501(*
* Copyright (c) 2017 Christiano F. Haesbaert <haesbaert@haesbaert.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)openUtilletversion_banner="SSH-2.0-awa_ssh_0.1"letmax_pkt_len=512*1024(* 512KB should be enough *)letmax_len=256*1024(* 256KB for a field is enough *)letchannel_win_len=(* 4MB channel window *)Int32.of_int(4*1024*1000)letchannel_win_adj_threshold=(* Refresh window if below 2MB *)Int32.of_int(2*1024*1000)letchannel_max_pkt_len=(* Must be smaller than max_pkt_len *)Int32.of_int(64*1024)letmax_channels=1024(* 1024 maximum channels per connection *)letmin_dh,n,max_dh=2048l,3072l,8192lletguard_sshlenlen=guard(len>=0&&len<=max_len)(sprintf"Bad length: %d"len)letguard_sshlen_exnlen=matchguard_sshlenlenwithOk()->()|Errore->invalid_argetypemessage_id=|MSG_DISCONNECT[@id1]|MSG_IGNORE[@id2]|MSG_UNIMPLEMENTED[@id3]|MSG_DEBUG[@id4]|MSG_SERVICE_REQUEST[@id5]|MSG_SERVICE_ACCEPT[@id6]|MSG_EXT_INFO[@id7]|MSG_KEXINIT[@id20]|MSG_NEWKEYS[@id21]|MSG_KEX_0[@id30]|MSG_KEX_1[@id31]|MSG_KEX_2[@id32]|MSG_KEX_3[@id33]|MSG_KEX_4[@id34]|MSG_USERAUTH_REQUEST[@id50]|MSG_USERAUTH_FAILURE[@id51]|MSG_USERAUTH_SUCCESS[@id52]|MSG_USERAUTH_BANNER[@id53]|MSG_USERAUTH_1[@id60]|MSG_USERAUTH_2[@id61]|MSG_GLOBAL_REQUEST[@id80]|MSG_REQUEST_SUCCESS[@id81]|MSG_REQUEST_FAILURE[@id82]|MSG_CHANNEL_OPEN[@id90]|MSG_CHANNEL_OPEN_CONFIRMATION[@id91]|MSG_CHANNEL_OPEN_FAILURE[@id92]|MSG_CHANNEL_WINDOW_ADJUST[@id93]|MSG_CHANNEL_DATA[@id94]|MSG_CHANNEL_EXTENDED_DATA[@id95]|MSG_CHANNEL_EOF[@id96]|MSG_CHANNEL_CLOSE[@id97]|MSG_CHANNEL_REQUEST[@id98]|MSG_CHANNEL_SUCCESS[@id99]|MSG_CHANNEL_FAILURE[@id100]|MSG_VERSION[@id-1]letmessage_id_to_int=function|MSG_DISCONNECT->1|MSG_IGNORE->2|MSG_UNIMPLEMENTED->3|MSG_DEBUG->4|MSG_SERVICE_REQUEST->5|MSG_SERVICE_ACCEPT->6|MSG_EXT_INFO->7|MSG_KEXINIT->20|MSG_NEWKEYS->21|MSG_KEX_0->30|MSG_KEX_1->31|MSG_KEX_2->32|MSG_KEX_3->33|MSG_KEX_4->34|MSG_USERAUTH_REQUEST->50|MSG_USERAUTH_FAILURE->51|MSG_USERAUTH_SUCCESS->52|MSG_USERAUTH_BANNER->53|MSG_USERAUTH_1->60|MSG_USERAUTH_2->61|MSG_GLOBAL_REQUEST->80|MSG_REQUEST_SUCCESS->81|MSG_REQUEST_FAILURE->82|MSG_CHANNEL_OPEN->90|MSG_CHANNEL_OPEN_CONFIRMATION->91|MSG_CHANNEL_OPEN_FAILURE->92|MSG_CHANNEL_WINDOW_ADJUST->93|MSG_CHANNEL_DATA->94|MSG_CHANNEL_EXTENDED_DATA->95|MSG_CHANNEL_EOF->96|MSG_CHANNEL_CLOSE->97|MSG_CHANNEL_REQUEST->98|MSG_CHANNEL_SUCCESS->99|MSG_CHANNEL_FAILURE->100|MSG_VERSION->-1letint_to_message_id=function|1->SomeMSG_DISCONNECT|2->SomeMSG_IGNORE|3->SomeMSG_UNIMPLEMENTED|4->SomeMSG_DEBUG|5->SomeMSG_SERVICE_REQUEST|6->SomeMSG_SERVICE_ACCEPT|7->SomeMSG_EXT_INFO|20->SomeMSG_KEXINIT|21->SomeMSG_NEWKEYS|30->SomeMSG_KEX_0|31->SomeMSG_KEX_1|32->SomeMSG_KEX_2|33->SomeMSG_KEX_3|34->SomeMSG_KEX_4|50->SomeMSG_USERAUTH_REQUEST|51->SomeMSG_USERAUTH_FAILURE|52->SomeMSG_USERAUTH_SUCCESS|53->SomeMSG_USERAUTH_BANNER|60->SomeMSG_USERAUTH_1|61->SomeMSG_USERAUTH_2|80->SomeMSG_GLOBAL_REQUEST|81->SomeMSG_REQUEST_SUCCESS|82->SomeMSG_REQUEST_FAILURE|90->SomeMSG_CHANNEL_OPEN|91->SomeMSG_CHANNEL_OPEN_CONFIRMATION|92->SomeMSG_CHANNEL_OPEN_FAILURE|93->SomeMSG_CHANNEL_WINDOW_ADJUST|94->SomeMSG_CHANNEL_DATA|95->SomeMSG_CHANNEL_EXTENDED_DATA|96->SomeMSG_CHANNEL_EOF|97->SomeMSG_CHANNEL_CLOSE|98->SomeMSG_CHANNEL_REQUEST|99->SomeMSG_CHANNEL_SUCCESS|100->SomeMSG_CHANNEL_FAILURE|-1->SomeMSG_VERSION|_->Nonetypekexinit={cookie:Cstruct.t;kex_algs:stringlist;ext_info:[`Ext_info_c|`Ext_info_s]option;server_host_key_algs:stringlist;encryption_algs_ctos:stringlist;encryption_algs_stoc:stringlist;mac_algs_ctos:stringlist;mac_algs_stoc:stringlist;compression_algs_ctos:stringlist;compression_algs_stoc:stringlist;languages_ctos:stringlist;languages_stoc:stringlist;first_kex_packet_follows:bool;rawkex:Cstruct.t;(* raw kexinit *)}letpp_kexinitppfkex=letstring_of_ext_info=function|None->"no ext-info"|Some`Ext_info_c->"ext-info-c"|Some`Ext_info_s->"ext-info-s"inletpp_sl=Fmt.(list~sep:(any", ")string)inFmt.pfppf"cookie %a@.kex algorithms %a@.ext_info %s@.server host key algorithms %a@. \
encryption algorithms client to server %a@.encryption algorithms server to client %a@. \
mac algorithms client to server %a@.mac algorithms server to client %a@. \
compression algorithms client to server %a@.compression algorithms server to client %a@. \
languages client to server %a@.languages server to client %a@. \
first key exchange packet follows %B@.raw kex %a"Cstruct.hexdump_ppkex.cookiepp_slkex.kex_algs(string_of_ext_infokex.ext_info)pp_slkex.server_host_key_algspp_slkex.encryption_algs_ctospp_slkex.encryption_algs_stocpp_slkex.mac_algs_ctospp_slkex.mac_algs_stocpp_slkex.compression_algs_ctospp_slkex.compression_algs_stocpp_slkex.languages_ctospp_slkex.languages_stockex.first_kex_packet_followsCstruct.hexdump_ppkex.rawkextypeextension=Extensionof{name:string;value:string}letpp_extensionppf(Extension{name;value})=Fmt.pfppf"%s=%S"namevaluetypedisconnect_code=|DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT[@id1]|DISCONNECT_PROTOCOL_ERROR[@id2]|DISCONNECT_KEY_EXCHANGE_FAILED[@id3]|DISCONNECT_RESERVED[@id4]|DISCONNECT_MAC_ERROR[@id5]|DISCONNECT_COMPRESSION_ERROR[@id6]|DISCONNECT_SERVICE_NOT_AVAILABLE[@id7]|DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED[@id8]|DISCONNECT_HOST_KEY_NOT_VERIFIABLE[@id9]|DISCONNECT_CONNECTION_LOST[@id10]|DISCONNECT_BY_APPLICATION[@id11]|DISCONNECT_TOO_MANY_CONNECTIONS[@id12]|DISCONNECT_AUTH_CANCELLED_BY_USER[@id13]|DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE[@id14]|DISCONNECT_ILLEGAL_USER_NAME[@id15]letdisconnect_code_to_int=function|DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT->1l|DISCONNECT_PROTOCOL_ERROR->2l|DISCONNECT_KEY_EXCHANGE_FAILED->3l|DISCONNECT_RESERVED->4l|DISCONNECT_MAC_ERROR->5l|DISCONNECT_COMPRESSION_ERROR->6l|DISCONNECT_SERVICE_NOT_AVAILABLE->7l|DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED->8l|DISCONNECT_HOST_KEY_NOT_VERIFIABLE->9l|DISCONNECT_CONNECTION_LOST->10l|DISCONNECT_BY_APPLICATION->11l|DISCONNECT_TOO_MANY_CONNECTIONS->12l|DISCONNECT_AUTH_CANCELLED_BY_USER->13l|DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE->14l|DISCONNECT_ILLEGAL_USER_NAME->15lletint_to_disconnect_code=function|1l->DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT|2l->DISCONNECT_PROTOCOL_ERROR|3l->DISCONNECT_KEY_EXCHANGE_FAILED|4l->DISCONNECT_RESERVED|5l->DISCONNECT_MAC_ERROR|6l->DISCONNECT_COMPRESSION_ERROR|7l->DISCONNECT_SERVICE_NOT_AVAILABLE|8l->DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED|9l->DISCONNECT_HOST_KEY_NOT_VERIFIABLE|10l->DISCONNECT_CONNECTION_LOST|11l->DISCONNECT_BY_APPLICATION|12l->DISCONNECT_TOO_MANY_CONNECTIONS|13l->DISCONNECT_AUTH_CANCELLED_BY_USER|14l->DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE|15l->DISCONNECT_ILLEGAL_USER_NAME|_->DISCONNECT_PROTOCOL_ERROR(* Mock up *)letdisconnect_code_to_string=function|DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT->"Host not allowed to connect"|DISCONNECT_PROTOCOL_ERROR->"Protocol error"|DISCONNECT_KEY_EXCHANGE_FAILED->"Key exchange failed"|DISCONNECT_RESERVED->"Reserved"|DISCONNECT_MAC_ERROR->"MAC error"|DISCONNECT_COMPRESSION_ERROR->"Compression error"|DISCONNECT_SERVICE_NOT_AVAILABLE->"Service not available"|DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED->"Protocol version not supported"|DISCONNECT_HOST_KEY_NOT_VERIFIABLE->"Host key not verifiable"|DISCONNECT_CONNECTION_LOST->"Connection lost"|DISCONNECT_BY_APPLICATION->"Disconnected by application"|DISCONNECT_TOO_MANY_CONNECTIONS->"Too many connections"|DISCONNECT_AUTH_CANCELLED_BY_USER->"Authentication cancelled by user"|DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE->"No more authentication methods available"|DISCONNECT_ILLEGAL_USER_NAME->"Illegal user name"(* Channel open codes *)typechannel_open_code=|OPEN_ADMINISTRATIVELY_PROHIBITED[@id1]|OPEN_CONNECT_FAILED[@id2]|OPEN_UNKNOWN_CHANNEL_TYPE[@id3]|OPEN_RESOURCE_SHORTAGE[@id4]letchannel_open_code_to_int=function|OPEN_ADMINISTRATIVELY_PROHIBITED->1l|OPEN_CONNECT_FAILED->2l|OPEN_UNKNOWN_CHANNEL_TYPE->3l|OPEN_RESOURCE_SHORTAGE->4lletint_to_channel_open_code=function|1l->SomeOPEN_ADMINISTRATIVELY_PROHIBITED|2l->SomeOPEN_CONNECT_FAILED|3l->SomeOPEN_UNKNOWN_CHANNEL_TYPE|4l->SomeOPEN_RESOURCE_SHORTAGE|_->Nonetypempint=Z.ttypeglobal_request=|Tcpip_forwardof(string*int32)|Cancel_tcpip_forwardof(string*int32)|Unknown_requestofstringtypechannel_request=|Pty_reqof(string*int32*int32*int32*int32*string)|X11_reqof(bool*string*string*int32)|Envof(string*string)|Shell|Execofstring|Subsystemofstring|Window_changeof(int32*int32*int32*int32)|Xon_xoffofbool|Signalofstring|Exit_statusofint32|Exit_signalof(string*bool*string*string)|Raw_dataofCstruct.ttypechannel_open=|Session|X11of(string*int32)|Forwarded_tcpipof(string*int32*string*int32)|Direct_tcpipof(string*int32*string*int32)|Raw_dataofCstruct.t(*
* Protocol Authentication
*)typepassword=stringtypeauth_method=|Pubkeyofstring*Cstruct.t*(string*string)option|Passwordofpassword*passwordoption|Keyboard_interactiveofstringoption*stringlist|Authnoneletpp_auth_methodppf=function|Pubkey(_sig_alg_raw,_pub_raw,_signature)->Fmt.stringppf"publickey"|Password(_,_)->Fmt.stringppf"password"|Keyboard_interactive(_,_)->Fmt.stringppf"keyboard-interactive"|Authnone->Fmt.stringppf"none"letopt_eqfab=matcha,bwith|None,None->true|Somea,Someb->fab|None,Some_|Some_,None->falseletauth_method_equalab=matcha,bwith|Pubkey(sig_alg_raw_a,key_a,signature_a),Pubkey(sig_alg_raw_b,key_b,signature_b)->letsig_equal(sig_alg_a,sig_a)(sig_alg_b,sig_b)=sig_alg_a=sig_alg_b&&String.equalsig_asig_binString.equalsig_alg_raw_asig_alg_raw_b&&Cstruct.equalkey_akey_b&&opt_eqsig_equalsignature_asignature_b|Password(p_a,popt_a),Password(p_b,popt_b)->String.equalp_ap_b&&opt_eqString.equalpopt_apopt_b|Keyboard_interactive(l_a,sub_a),Keyboard_interactive(l_b,sub_b)->opt_eqString.equall_al_b&&List.for_all2String.equalsub_asub_b|Authnone,Authnone->true|_->falsetypemessage=|Msg_disconnectof(disconnect_code*string*string)|Msg_ignoreofstring|Msg_unimplementedofint32|Msg_debugof(bool*string*string)|Msg_service_requestofstring|Msg_service_acceptofstring|Msg_kexinitofkexinit|Msg_ext_infoofextensionlist|Msg_newkeys|Msg_kexdh_replyofHostkey.pub*mpint*(Hostkey.alg*string)|Msg_kexdh_initofmpint(* from RFC 5656 / 8731 *)|Msg_kexecdh_replyofHostkey.pub*mpint*(Hostkey.alg*string)|Msg_kexecdh_initofmpint(* from RFC 4419 *)(* there's as well a Msg_kexdh_gex_request_old with only a single int32 *)|Msg_kexdh_gex_requestofint32*int32*int32|Msg_kexdh_gex_groupofmpint*mpint|Msg_kexdh_gex_initofmpint|Msg_kexdh_gex_replyofHostkey.pub*mpint*(Hostkey.alg*string)|Msg_kexofmessage_id*Cstruct.t|Msg_userauth_requestof(string*string*auth_method)|Msg_userauth_failureof(stringlist*bool)|Msg_userauth_success|Msg_userauth_bannerof(string*string)|Msg_userauth_1ofCstruct.t|Msg_userauth_2ofCstruct.t|Msg_userauth_pk_okofHostkey.pub|Msg_userauth_info_requestofstring*string*string*(string*bool)list|Msg_userauth_info_responseofpasswordlist|Msg_global_requestof(string*bool*global_request)|Msg_request_successofCstruct.toption|Msg_request_failure|Msg_channel_openof(int32*int32*int32*channel_open)|Msg_channel_open_confirmationof(int32*int32*int32*int32*Cstruct.t)|Msg_channel_open_failureof(int32*int32*string*string)|Msg_channel_window_adjustof(int32*int32)|Msg_channel_dataof(int32*Cstruct.t)|Msg_channel_extended_dataof(int32*int32*Cstruct.t)|Msg_channel_eofofint32|Msg_channel_closeofint32|Msg_channel_requestof(int32*bool*channel_request)|Msg_channel_successofint32|Msg_channel_failureofint32|Msg_versionofstring(* Mocked version *)letmessage_to_id=function|Msg_disconnect_->MSG_DISCONNECT|Msg_ignore_->MSG_IGNORE|Msg_unimplemented_->MSG_UNIMPLEMENTED|Msg_debug_->MSG_DEBUG|Msg_service_request_->MSG_SERVICE_REQUEST|Msg_service_accept_->MSG_SERVICE_ACCEPT|Msg_kexinit_->MSG_KEXINIT|Msg_ext_info_->MSG_EXT_INFO|Msg_newkeys->MSG_NEWKEYS|Msg_kexdh_init_->MSG_KEX_0|Msg_kexdh_reply_->MSG_KEX_1|Msg_kexecdh_init_->MSG_KEX_0|Msg_kexecdh_reply_->MSG_KEX_1|Msg_kexdh_gex_request_->MSG_KEX_4|Msg_kexdh_gex_group_->MSG_KEX_1|Msg_kexdh_gex_init_->MSG_KEX_2|Msg_kexdh_gex_reply_->MSG_KEX_3|Msg_kex(id,_)->id|Msg_userauth_request_->MSG_USERAUTH_REQUEST|Msg_userauth_failure_->MSG_USERAUTH_FAILURE|Msg_userauth_success->MSG_USERAUTH_SUCCESS|Msg_userauth_banner_->MSG_USERAUTH_BANNER|Msg_userauth_1_->MSG_USERAUTH_1|Msg_userauth_2_->MSG_USERAUTH_2|Msg_userauth_pk_ok_->MSG_USERAUTH_1|Msg_userauth_info_request_->MSG_USERAUTH_1|Msg_userauth_info_response_->MSG_USERAUTH_2|Msg_global_request_->MSG_GLOBAL_REQUEST|Msg_request_success_->MSG_REQUEST_SUCCESS|Msg_request_failure->MSG_REQUEST_FAILURE|Msg_channel_open_->MSG_CHANNEL_OPEN|Msg_channel_open_confirmation_->MSG_CHANNEL_OPEN_CONFIRMATION|Msg_channel_open_failure_->MSG_CHANNEL_OPEN_FAILURE|Msg_channel_window_adjust_->MSG_CHANNEL_WINDOW_ADJUST|Msg_channel_data_->MSG_CHANNEL_DATA|Msg_channel_extended_data_->MSG_CHANNEL_EXTENDED_DATA|Msg_channel_eof_->MSG_CHANNEL_EOF|Msg_channel_close_->MSG_CHANNEL_CLOSE|Msg_channel_request_->MSG_CHANNEL_REQUEST|Msg_channel_success_->MSG_CHANNEL_SUCCESS|Msg_channel_failure_->MSG_CHANNEL_FAILURE|Msg_version_->MSG_VERSIONletpp_langppflang=iflang=""then()elseFmt.pfppf"(lang %s)"langletpp_messageppf=function|Msg_disconnect(code,desc,lang)->Fmt.pfppf"disconnect %s %s%a"(disconnect_code_to_stringcode)descpp_langlang|Msg_ignored->Fmt.pfppf"ignore %s"d|Msg_unimplementedy->Fmt.pfppf"unimplemented %lu"y|Msg_debug(display,msg,lang)->Fmt.pfppf"debug (display %B) %s%a"displaymsgpp_langlang|Msg_service_requests->Fmt.pfppf"service request %s"s|Msg_service_accepts->Fmt.pfppf"service accept %s"s|Msg_kexinitkex->Fmt.pfppf"kexinit %a"pp_kexinitkex|Msg_ext_infoextensions->Fmt.pfppf"extensions [%a]"Fmt.(listpp_extension)extensions|Msg_newkeys->Fmt.pfppf"newkeys"|Msg_kexdh_init_z->Fmt.pfppf"KEX DH Init"|Msg_kexdh_reply(_hostkey,_z,(_alg,_share))->Fmt.pfppf"KEX DH reply"|Msg_kexecdh_init_z->Fmt.pfppf"KEX ECDH Init"|Msg_kexecdh_reply(_hostkey,_z,(_alg,_share))->Fmt.pfppf"KEX ECDH reply"|Msg_kexdh_gex_request(_a,_b,_c)->Fmt.pfppf"KEX DH gex request"|Msg_kexdh_gex_group(_z,_z2)->Fmt.pfppf"KEX DH gex group"|Msg_kexdh_gex_init_z->Fmt.pfppf"KEX DH gex init"|Msg_kexdh_gex_reply(_hostkey,_z,(_alg,_share))->Fmt.pfppf"KEX DH gex reply"|Msg_kex(id,_)->Fmt.pfppf"KEX %u"(message_id_to_intid)|Msg_userauth_request(user,service,auth)->Fmt.pfppf"userauth request %s (service %s) %a"userservicepp_auth_methodauth|Msg_userauth_failure(methods,partial)->Fmt.pfppf"userauth failure (partial %B) %a"partialFmt.(list~sep:(any", ")string)methods|Msg_userauth_success->Fmt.pfppf"userauth success"|Msg_userauth_banner(msg,lang)->Fmt.pfppf"userauth banner%a %s"pp_langlangmsg|Msg_userauth_1_->Fmt.pfppf"userauth 1"|Msg_userauth_2_->Fmt.pfppf"userauth 2"|Msg_userauth_pk_ok_->Fmt.pfppf"userauth pk ok"|Msg_userauth_info_request_->Fmt.pfppf"userauth info request"|Msg_userauth_info_response_->Fmt.pfppf"userauth info response"|Msg_global_request_->Fmt.pfppf"global request"|Msg_request_success_->Fmt.pfppf"request success"|Msg_request_failure->Fmt.pfppf"request failure"|Msg_channel_open_->Fmt.pfppf"channel open"|Msg_channel_open_confirmation_->Fmt.pfppf"channel open confirmation"|Msg_channel_open_failure_->Fmt.pfppf"channel open failure"|Msg_channel_window_adjust_->Fmt.pfppf"channel window adjust"|Msg_channel_data_->Fmt.pfppf"channel data"|Msg_channel_extended_data_->Fmt.pfppf"channel extended data"|Msg_channel_eof_->Fmt.pfppf"channel eof"|Msg_channel_close_->Fmt.pfppf"channel close"|Msg_channel_request_->Fmt.pfppf"channel request"|Msg_channel_success_->Fmt.pfppf"channel success"|Msg_channel_failure_->Fmt.pfppf"channel failure"|Msg_versionv->Fmt.pfppf"version %s"vletmessage_to_intmsg=message_id_to_int(message_to_idmsg)letdisconnect_msgcodes=Msg_disconnect(code,s,"")