Client: do not expose insecure functions (betanet)

This commit is contained in:
Vincent Bernardoff 2018-06-29 23:04:29 +02:00 committed by Benjamin Canou
parent e92e1aee17
commit 99e5cd3186
4 changed files with 166 additions and 115 deletions

View File

@ -14,71 +14,89 @@ let disable_disclaimer =
| Some ("yes" | "y" | "YES" | "Y") -> true | Some ("yes" | "y" | "YES" | "Y") -> true
| _ -> false | _ -> false
let display_warning_banner ctxt = let default () =
if disable_disclaimer then if not disable_disclaimer then
Lwt.return () Format.eprintf
else "@[<v 2>@{<warning>@{<title>Warning@}@}@,@,\
let default () = \ This is @{<warning>NOT@} the Tezos Mainnet.@,\
Format.eprintf \ The Tezos Mainnet is not yet released.@,\
"@[<v 2>@{<warning>@{<title>Warning@}@}@,@,\ @,\
\ This is @{<warning>NOT@} the Tezos Mainnet.@,\ \ Use your fundraiser keys @{<warning>AT YOUR OWN RISK@}.@,\
\ The Tezos Mainnet is not yet released.@,\ All transactions happening on the Betanet @{<warning>are expected to be valid in the Mainnet@}.@,\
@,\ \ In doubt, we recommend that you wait for the lunch of the Mainnet.@]@\n@."
\ Use your fundraiser keys @{<warning>AT YOUR OWN RISK@}.@,\
All transactions happening on the Betanet @{<warning>are expected to be valid in the Mainnet@}.@,\ let zeronet () =
\ In doubt, we recommend that you wait for the lunch of the Mainnet.@]@\n@." ; if not disable_disclaimer then
Lwt.return_unit in Format.eprintf
Shell_services.P2p.versions ctxt >>= function "@[<v 2>@{<warning>@{<title>Warning@}@}@,@,\
| Error _ -> default () \ This is @{<warning>NOT@} the Tezos Mainnet.@,\
| Ok versions -> \ The Tezos Mainnet is not yet released.@,\
match String.split_on_char '_' (List.hd versions).name with @,\
| "TEZOS" :: "ZERONET" :: _date :: [] -> \ The node you are connecting to claims to be running on the@,\
Format.eprintf \ @{<warning>Tezos Zeronet DEVELOPMENT NETWORK@}.@,\
"@[<v 2>@{<warning>@{<title>Warning@}@}@,@,\ \ Do @{<warning>NOT@} use your fundraiser keys on this network.@,\
\ This is @{<warning>NOT@} the Tezos Mainnet.@,\ Zeronet is a testing network, with free tokens and frequent resets.@]@\n@."
\ The Tezos Mainnet is not yet released.@,\
@,\ let alphanet () =
\ The node you are connecting to claims to be running on the@,\ if not disable_disclaimer then
\ @{<warning>Tezos Zeronet DEVELOPMENT NETWORK@}.@,\ Format.eprintf
\ Do @{<warning>NOT@} use your fundraiser keys on this network.@,\ "@[<v 2>@{<warning>@{<title>Warning@}@}@,@,\
Zeronet is a testing network, with free tokens and frequent resets.@]@\n@." ; \ This is @{<warning>NOT@} the Tezos Mainnet.@,\
Lwt.return_unit \ The Tezos Mainnet is not yet released.@,\
| "TEZOS" :: "ALPHANET" :: _date :: [] -> @,\
Format.eprintf \ The node you are connecting to claims to be running on the@,\
"@[<v 2>@{<warning>@{<title>Warning@}@}@,@,\ \ @{<warning>Tezos Alphanet DEVELOPMENT NETWORK.@}@,\
\ This is @{<warning>NOT@} the Tezos Mainnet.@,\ \ Do @{<warning>NOT@} use your fundraiser keys on this network.@,\
\ The Tezos Mainnet is not yet released.@,\ \ Alphanet is a testing network, with free tokens.@]@\n@."
@,\
\ The node you are connecting to claims to be running on the@,\ let betanet () =
\ @{<warning>Tezos Alphanet DEVELOPMENT NETWORK.@}@,\ if not disable_disclaimer then
\ Do @{<warning>NOT@} use your fundraiser keys on this network.@,\ Format.eprintf
\ Alphanet is a testing network, with free tokens.@]@\n@." ; "@[<v 2>@{<warning>@{<title>Warning@}@}@,@,\
Lwt.return_unit \ This is @{<warning>NOT@} the Tezos Mainnet.@,\
| "TEZOS" :: "BETANET" :: _date :: [] -> \ The Tezos Mainnet is not yet released.@,\
Format.eprintf @,\
"@[<v 2>@{<warning>@{<title>Warning@}@}@,@,\ \ The node you are connecting to claims to be running on the@,\
\ This is @{<warning>NOT@} the Tezos Mainnet.@,\ \ @{<warning>Tezos Betanet EXPERIMENTAL NETWORK@}.@,\
\ The Tezos Mainnet is not yet released.@,\ \ Betanet is a pre-release experimental network and comes with no warranty.@,\
@,\ \ Use your fundraiser keys on this network @{<warning>AT YOUR OWN RISK@}.@,\
\ The node you are connecting to claims to be running on the@,\ \ All transactions happening on the Betanet @{<warning>are expected to be valid in the Mainnet@}.@,\
\ @{<warning>Tezos Betanet EXPERIMENTAL NETWORK@}.@,\ \ If in doubt, we recommend that you wait for the Mainnet lunch.@]@\n@."
\ Betanet is a pre-release experimental network and comes with no warranty.@,\
\ Use your fundraiser keys on this network @{<warning>AT YOUR OWN RISK@}.@,\ let sandbox () =
\ All transactions happening on the Betanet @{<warning>are expected to be valid in the Mainnet@}.@,\ if not disable_disclaimer then
\ If in doubt, we recommend that you wait for the Mainnet lunch.@]@\n@." ; Format.eprintf
Lwt.return_unit "@[<v 2>@{<warning>@{<title>Warning@}@}@,@,\
| "TEZOS" :: _date :: [] -> \ This is @{<warning>NOT@} the Tezos Mainnet.@,\
Format.eprintf \ The Tezos Mainnet is not yet released.@,\
"@[<v 2>@{<warning>@{<title>Warning@}@}@,@,\ @,\
\ This is @{<warning>NOT@} the Tezos Mainnet.@,\ \ The node you are connecting to claims to be running in a@,\
\ The Tezos Mainnet is not yet released.@,\ \ @{<warning>Tezos TEST SANDBOX@}.@,\
@,\ \ Do @{<warning>NOT@} use your fundraiser keys on this network.@,\
\ The node you are connecting to claims to be running in a@,\ You should not see this message if you are not a developer.@]@\n@."
\ @{<warning>Tezos TEST SANDBOX@}.@,\
\ Do @{<warning>NOT@} use your fundraiser keys on this network.@,\ let check_version ctxt =
You should not see this message if you are not a developer.@]@\n@." ; Shell_services.P2p.versions ctxt >>= function
Lwt.return_unit | Error _ ->
| _ -> default () default () ;
Lwt.return_none
| Ok versions ->
match String.split_on_char '_' (List.hd versions).name with
| "TEZOS" :: "ZERONET" :: _date :: [] ->
zeronet () ;
Lwt.return_some `Zeronet
| "TEZOS" :: "ALPHANET" :: _date :: [] ->
alphanet () ;
Lwt.return_some `Alphanet
| "TEZOS" :: "BETANET" :: _date :: [] ->
betanet () ;
Lwt.return_some `Betanet
| "TEZOS" :: _date :: [] ->
sandbox () ;
Lwt.return_some `Sandbox
| _ ->
default () ;
Lwt.return_none
let get_commands_for_version ctxt block protocol = let get_commands_for_version ctxt block protocol =
Shell_services.Blocks.protocols ctxt ~block () >>= function Shell_services.Blocks.protocols ctxt ~block () >>= function
@ -111,14 +129,14 @@ let get_commands_for_version ctxt block protocol =
end end
let select_commands ctxt { block ; protocol } = let select_commands ctxt { block ; protocol } =
display_warning_banner ctxt >>= fun () -> check_version ctxt >>= fun version ->
get_commands_for_version ctxt block protocol >>|? fun (_, commands_for_version) -> get_commands_for_version ctxt block protocol >>|? fun (_, commands_for_version) ->
Client_rpc_commands.commands @ Client_rpc_commands.commands @
List.map List.map
(Clic.map_command (Clic.map_command
(fun (o : Client_context.full) -> (o :> Client_context.io_wallet))) (fun (o : Client_context.full) -> (o :> Client_context.io_wallet)))
(Tezos_signer_backends.Ledger.commands () @ (Tezos_signer_backends.Ledger.commands () @
Client_keys_commands.commands ()) @ Client_keys_commands.commands version) @
Client_helpers_commands.commands () @ Client_helpers_commands.commands () @
commands_for_version commands_for_version

View File

@ -67,7 +67,7 @@ let magic_bytes_arg =
is expected, separated by commas.")) is expected, separated by commas."))
let commands base_dir require_auth = let commands base_dir require_auth =
Client_keys_commands.commands () @ Client_keys_commands.commands None @
Tezos_signer_backends.Ledger.commands () @ Tezos_signer_backends.Ledger.commands () @
[ command ~group [ command ~group
~desc: "Launch a signer daemon over a TCP socket." ~desc: "Launch a signer daemon over a TCP socket."

View File

@ -13,17 +13,6 @@ let group =
{ Clic.name = "keys" ; { Clic.name = "keys" ;
title = "Commands for managing the wallet of cryptographic keys" } title = "Commands for managing the wallet of cryptographic keys" }
let encrypted_switch () =
if List.exists
(fun (scheme, _) ->
scheme = Tezos_signer_backends.Unencrypted.scheme)
(Client_keys.registered_signers ()) then
Clic.switch
~long:"encrypted"
~doc:("Encrypt the key on-disk") ()
else
Clic.constant true
let sig_algo_arg = let sig_algo_arg =
Clic.default_arg Clic.default_arg
~doc:"use custom signature algorithm" ~doc:"use custom signature algorithm"
@ -156,8 +145,18 @@ let rec input_fundraiser_params (cctxt : #Client_context.io_wallet) =
| true -> return sk | true -> return sk
| false -> input_fundraiser_params cctxt | false -> input_fundraiser_params cctxt
let commands () : Client_context.io_wallet Clic.command list = let commands version : Client_context.io_wallet Clic.command list =
let open Clic in let open Clic in
let encrypted_switch () =
if List.exists
(fun (scheme, _) ->
scheme = Tezos_signer_backends.Unencrypted.scheme)
(Client_keys.registered_signers ()) then
Clic.switch
~long:"encrypted"
~doc:("Encrypt the key on-disk") ()
else
Clic.constant true in
let show_private_switch = let show_private_switch =
switch switch
~long:"show-secret" ~long:"show-secret"
@ -188,39 +187,73 @@ let commands () : Client_context.io_wallet Clic.command list =
n S.title Format.pp_print_text S.description) n S.title Format.pp_print_text S.description)
signers >>= return) ; signers >>= return) ;
command ~group ~desc: "Generate a pair of keys." begin match version with
(args3 (Secret_key.force_switch ()) sig_algo_arg (encrypted_switch ())) | Some `Betanet ->
(prefixes [ "gen" ; "keys" ] command ~group ~desc: "Generate a pair of keys."
@@ Secret_key.fresh_alias_param (args2 (Secret_key.force_switch ()) sig_algo_arg)
@@ stop) (prefixes [ "gen" ; "keys" ]
(fun (force, algo, encrypted) name (cctxt : Client_context.io_wallet) -> @@ Secret_key.fresh_alias_param
Secret_key.of_fresh cctxt force name >>=? fun name -> @@ stop)
let (pkh, pk, sk) = Signature.generate_key ~algo () in (fun (force, algo) name (cctxt : Client_context.io_wallet) ->
let pk_uri = Tezos_signer_backends.Unencrypted.make_pk pk in Secret_key.of_fresh cctxt force name >>=? fun name ->
begin let (pkh, pk, sk) = Signature.generate_key ~algo () in
if encrypted then let pk_uri = Tezos_signer_backends.Unencrypted.make_pk pk in
Tezos_signer_backends.Encrypted.encrypt cctxt sk Tezos_signer_backends.Encrypted.encrypt cctxt sk >>=? fun sk_uri ->
else register_key cctxt ~force (pkh, pk_uri, sk_uri) name)
return (Tezos_signer_backends.Unencrypted.make_sk sk) | _ ->
end >>=? fun sk_uri -> command ~group ~desc: "Generate a pair of keys."
register_key cctxt ~force (pkh, pk_uri, sk_uri) name) ; (args3 (Secret_key.force_switch ()) sig_algo_arg (encrypted_switch ()))
(prefixes [ "gen" ; "keys" ]
@@ Secret_key.fresh_alias_param
@@ stop)
(fun (force, algo, encrypted) name (cctxt : Client_context.io_wallet) ->
Secret_key.of_fresh cctxt force name >>=? fun name ->
let (pkh, pk, sk) = Signature.generate_key ~algo () in
let pk_uri = Tezos_signer_backends.Unencrypted.make_pk pk in
begin
if encrypted then
Tezos_signer_backends.Encrypted.encrypt cctxt sk
else
return (Tezos_signer_backends.Unencrypted.make_sk sk)
end >>=? fun sk_uri ->
register_key cctxt ~force (pkh, pk_uri, sk_uri) name)
end ;
command ~group ~desc: "Generate keys including the given string." begin match version with
(args3 | Some `Betanet ->
(switch command ~group ~desc: "Generate keys including the given string."
~long:"prefix" (args2
~short:'P' (switch
~doc:"the key must begin with tz1[word]" ~long:"prefix"
()) ~short:'P'
(force_switch ()) ~doc:"the key must begin with tz1[word]"
(encrypted_switch ())) ())
(prefixes [ "gen" ; "vanity" ; "keys" ] (force_switch ()))
@@ Public_key_hash.fresh_alias_param (prefixes [ "gen" ; "vanity" ; "keys" ]
@@ prefix "matching" @@ Public_key_hash.fresh_alias_param
@@ (seq_of_param @@ string ~name:"words" ~desc:"string key must contain one of these words")) @@ prefix "matching"
(fun (prefix, force, encrypted) name containing (cctxt : Client_context.io_wallet) -> @@ (seq_of_param @@ string ~name:"words" ~desc:"string key must contain one of these words"))
Public_key_hash.of_fresh cctxt force name >>=? fun name -> (fun (prefix, force) name containing (cctxt : Client_context.io_wallet) ->
gen_keys_containing ~encrypted ~force ~prefix ~containing ~name cctxt) ; Public_key_hash.of_fresh cctxt force name >>=? fun name ->
gen_keys_containing ~encrypted:true ~force ~prefix ~containing ~name cctxt)
| _ ->
command ~group ~desc: "Generate keys including the given string."
(args3
(switch
~long:"prefix"
~short:'P'
~doc:"the key must begin with tz1[word]"
())
(force_switch ())
(encrypted_switch ()))
(prefixes [ "gen" ; "vanity" ; "keys" ]
@@ Public_key_hash.fresh_alias_param
@@ prefix "matching"
@@ (seq_of_param @@ string ~name:"words" ~desc:"string key must contain one of these words"))
(fun (prefix, force, encrypted) name containing (cctxt : Client_context.io_wallet) ->
Public_key_hash.of_fresh cctxt force name >>=? fun name ->
gen_keys_containing ~encrypted ~force ~prefix ~containing ~name cctxt)
end ;
command ~group ~desc: "Add a secret key to the wallet." command ~group ~desc: "Add a secret key to the wallet."
(args1 (Secret_key.force_switch ())) (args1 (Secret_key.force_switch ()))

View File

@ -7,6 +7,6 @@
(* *) (* *)
(**************************************************************************) (**************************************************************************)
val commands: unit -> Client_context.io_wallet Clic.command list val commands:
[`Zeronet | `Alphanet | `Betanet | `Sandbox] option ->
val encrypted_switch: unit -> (bool, 'a) Clic.arg Client_context.io_wallet Clic.command list