@@ -71,10 +71,47 @@ module TCP = struct
7171 >> = fun t -> create_connection t (ipaddr, port)
7272end
7373
74+ module SSH = struct
75+ include Awa_mirage. Make (Tcpip_stack_socket.V4V6. TCP )(Mclock )
76+
77+ type nonrec error =
78+ [ `TCP of TCP .error
79+ | `SSH of error ]
80+
81+ let pp_error ppf = function
82+ | `TCP err -> TCP. pp_error ppf err
83+ | `SSH err -> pp_error ppf err
84+
85+ type endpoint =
86+ { authenticator : Awa.Keys .authenticator option
87+ ; user : string
88+ ; path : string
89+ ; key : Awa.Hostkey .priv
90+ ; endpoint : TCP .endpoint }
91+
92+ let ( >> ? ) = Lwt_result. bind
93+ open Lwt.Infix
94+
95+ let read flow = read flow > |= Rresult.R. reword_error (fun err -> `SSH err)
96+
97+ let connect { authenticator; user; path; key; endpoint; } =
98+ let channel_request = Awa.Ssh. Exec (Fmt. str " git-upload-pack '%s'" path) in
99+ TCP. connect endpoint
100+ > |= Rresult.R. reword_error (fun err -> `TCP err) >> ? fun flow ->
101+ client_of_flow ?authenticator ~user key channel_request flow
102+ > |= Rresult.R. reword_error (fun err -> `SSH err)
103+ end
104+
74105let tcp_value, tcp_protocol = Mimic. register ~name: " tcp" (module TCP )
75106let domain_name = Mimic. make ~name: " domain-namme"
76107let port = Mimic. make ~name: " port"
77108
109+ let ssh_value, ssh_protocol = Mimic. register ~name: " ssh" (module SSH )
110+ let path = Mimic. make ~name: " path"
111+ let seed = Mimic. make ~name: " ssh-seed"
112+ let user = Mimic. make ~name: " user"
113+ let authenticator = Mimic. make ~name: " ssh-authenticator"
114+
78115let resolv ctx =
79116 let k domain_name port =
80117 match Unix. gethostbyname (Domain_name. to_string domain_name) with
@@ -84,16 +121,28 @@ let resolv ctx =
84121 in
85122 Mimic. fold tcp_value Mimic.Fun. [ req domain_name; dft port 9418 ] ~k ctx
86123
124+ let resolv_ssh ctx =
125+ let k authenticator sockaddr path user seed =
126+ let key = Awa.Keys. of_seed `Rsa seed in
127+ Lwt. return_some { SSH. authenticator; user; path; key; endpoint= sockaddr } in
128+ Mimic. fold ssh_value Mimic.Fun. [ opt authenticator; req tcp_value; req path; req user; req seed ] ~k ctx
129+
130+ let of_smart_git_endpoint edn ctx = match edn with
131+ | { Smart_git.Endpoint. scheme = `SSH v_user ; path = v_path ; host; } ->
132+ ctx |> Mimic. add domain_name host |> Mimic. add path v_path |> Mimic. add user v_user
133+ | { Smart_git.Endpoint. path = v_path ; host; _ } ->
134+ ctx |> Mimic. add domain_name host |> Mimic. add path v_path
135+
87136let main (_ssh_seed : string )
88137 (references : (Git.Reference.t * Git.Reference.t) list ) (directory : string )
89- ({ Smart_git.Endpoint. host; _ } as repository : Smart_git.Endpoint.t ) :
138+ (repository : Smart_git.Endpoint.t ) :
90139 (unit , 'error ) Lwt_result. t =
91140 let repo_root =
92141 (match directory with "" -> Sys. getcwd () | _ -> directory) |> Fpath. v
93142 in
94143 let ( >> ?= ) = Lwt_result. bind in
95144 let ( >>!= ) v f = Lwt_result. map_err f v in
96- let ctx = resolv Mimic. empty |> Mimic. add domain_name host in
145+ let ctx = Mimic. empty |> resolv |> resolv_ssh |> of_smart_git_endpoint repository in
97146 Store. v repo_root >>!= store_err >> ?= fun store ->
98147 let push_stdout = print_endline in
99148 let push_stderr = prerr_endline in
0 commit comments