Allow secure keypair input for solana-archiver and solana cli tools (#7106)

* Add seed phrase keypair recover to archiver

* Add seed phrase keypair to cli with ASK keyword

* cli main tweaks
This commit is contained in:
Justin Starry
2019-11-23 11:55:43 -05:00
committed by GitHub
parent 7f87ac4b65
commit b8cd0a1bc0
15 changed files with 218 additions and 108 deletions

View File

@@ -1,7 +1,13 @@
use clap::{crate_description, crate_name, Arg, ArgGroup, ArgMatches, SubCommand};
use console::style;
use solana_clap_utils::input_validators::is_url;
use solana_clap_utils::{
input_validators::is_url,
keypair::{
self, keypair_input, KeypairWithSource, ASK_SEED_PHRASE_ARG,
SKIP_SEED_PHRASE_VALIDATION_ARG,
},
};
use solana_cli::{
cli::{app, parse_command, process_command, CliCommandInfo, CliConfig, CliError},
config::{self, Config},
@@ -15,22 +21,25 @@ fn parse_settings(matches: &ArgMatches<'_>) -> Result<bool, Box<dyn error::Error
let parse_args = match matches.subcommand() {
("get", Some(subcommand_matches)) => {
if let Some(config_file) = matches.value_of("config_file") {
let default_cli_config = CliConfig::default();
let config = Config::load(config_file).unwrap_or_default();
if let Some(field) = subcommand_matches.value_of("specific_setting") {
let (value, default_value) = match field {
"url" => (config.url, default_cli_config.json_rpc_url),
"keypair" => (config.keypair, default_cli_config.keypair_path.unwrap()),
"url" => (config.url, CliConfig::default_json_rpc_url()),
"keypair" => (config.keypair_path, CliConfig::default_keypair_path()),
_ => unreachable!(),
};
println_name_value_or(&format!("* {}:", field), &value, &default_value);
} else {
println_name_value("Wallet Config:", config_file);
println_name_value_or("* url:", &config.url, &default_cli_config.json_rpc_url);
println_name_value_or(
"* url:",
&config.url,
&CliConfig::default_json_rpc_url(),
);
println_name_value_or(
"* keypair:",
&config.keypair,
&default_cli_config.keypair_path.unwrap(),
&config.keypair_path,
&CliConfig::default_keypair_path(),
);
}
} else {
@@ -48,12 +57,12 @@ fn parse_settings(matches: &ArgMatches<'_>) -> Result<bool, Box<dyn error::Error
config.url = url.to_string();
}
if let Some(keypair) = subcommand_matches.value_of("keypair") {
config.keypair = keypair.to_string();
config.keypair_path = keypair.to_string();
}
config.save(config_file)?;
println_name_value("Wallet Config Updated:", config_file);
println_name_value("* url:", &config.url);
println_name_value("* keypair:", &config.keypair);
println_name_value("* keypair:", &config.keypair_path);
} else {
println!(
"{} Either provide the `--config` arg or ensure home directory exists to use the default config location",
@@ -88,28 +97,37 @@ pub fn parse_args(matches: &ArgMatches<'_>) -> Result<CliConfig, Box<dyn error::
} = parse_command(&matches)?;
let (keypair, keypair_path) = if require_keypair {
let keypair_path = if matches.is_present("keypair") {
matches.value_of("keypair").unwrap().to_string()
} else if config.keypair != "" {
config.keypair
} else {
let default = CliConfig::default();
let maybe_keypair_path = default.keypair_path.unwrap();
if !std::path::Path::new(&maybe_keypair_path).exists() {
return Err(CliError::KeypairFileNotFound(
"Generate a new keypair with `solana-keygen new`".to_string(),
)
.into());
let KeypairWithSource { keypair, source } = keypair_input(&matches, "keypair")?;
match source {
keypair::Source::File => (
keypair,
Some(matches.value_of("keypair").unwrap().to_string()),
),
keypair::Source::SeedPhrase => (keypair, None),
keypair::Source::Generated => {
let keypair_path = if config.keypair_path != "" {
config.keypair_path
} else {
let default_keypair_path = CliConfig::default_keypair_path();
if !std::path::Path::new(&default_keypair_path).exists() {
return Err(CliError::KeypairFileNotFound(
"Generate a new keypair with `solana-keygen new`".to_string(),
)
.into());
}
default_keypair_path
};
let keypair = read_keypair_file(&keypair_path).or_else(|err| {
Err(CliError::BadParameter(format!(
"{}: Unable to open keypair file: {}",
err, keypair_path
)))
})?;
(keypair, Some(keypair_path))
}
maybe_keypair_path
};
let keypair = read_keypair_file(&keypair_path).or_else(|err| {
Err(CliError::BadParameter(format!(
"{}: Unable to open keypair file: {}",
err, keypair_path
)))
})?;
(keypair, Some(keypair_path.to_string()))
}
} else {
let default = CliConfig::default();
(default.keypair, None)
@@ -164,6 +182,21 @@ fn main() -> Result<(), Box<dyn error::Error>> {
.takes_value(true)
.help("/path/to/id.json"),
)
.arg(
Arg::with_name(ASK_SEED_PHRASE_ARG.name)
.long(ASK_SEED_PHRASE_ARG.long)
.value_name("KEYPAIR NAME")
.global(true)
.takes_value(true)
.possible_values(&["keypair"])
.help(ASK_SEED_PHRASE_ARG.help),
)
.arg(
Arg::with_name(SKIP_SEED_PHRASE_VALIDATION_ARG.name)
.long(SKIP_SEED_PHRASE_VALIDATION_ARG.long)
.global(true)
.help(SKIP_SEED_PHRASE_VALIDATION_ARG.help),
)
.subcommand(
SubCommand::with_name("get")
.about("Get cli config settings")