feat: add provisioning support

This commit is contained in:
JuliusHerrmann 2023-01-27 16:23:43 +01:00
parent 759be48b0e
commit a7bbbe95cc
2 changed files with 109 additions and 40 deletions

View File

@ -55,17 +55,18 @@ pub struct CliArgs {
fn main() { fn main() {
let args = CliArgs::parse(); let args = CliArgs::parse();
let mut user_provision_commands = vec![]; let mut user_provision_commands = vec![];
let mut provision_commands = vec![];
let mut pysim_outputs = vec![]; let mut pysim_outputs = vec![];
// parse the supplied card configs // parse the supplied card configs
let card_configs = parser::parse_csv(&args.csv).unwrap(); let card_configs = parser::parse_csv(&args.csv).unwrap();
for conf in card_configs { for mut conf in card_configs {
// create the arguments // get the ending of the IMSI to distinguish cards
let imsi_ending = String::from(&conf.IMSI[6..]); let imsi_ending = parser::get_imsi_ending(&mut conf);
// add command to be run on the open5gcore // calculate the new IMSI
user_provision_commands.push(format!("./provision_user.sh -S 001010000012345 -k {} -a 8000 -o 00000000000000000000000000000000 -s 000000000010 -t 0 -c 1 -u 0 -T 12345", String::from(&conf.IMSI))); parser::update_imsi(&mut conf, &args);
let pysim_args = conf.generate_pysim_args(&args); let pysim_args = parser::generate_pysim_args(&mut conf, &args);
println!("\n{}:", "EXECUTING".red()); println!("\n{}:", "EXECUTING".red());
print!("{}", args.bin); print!("{}", args.bin);
@ -84,16 +85,15 @@ fn main() {
for pysim_arg in pysim_args { for pysim_arg in pysim_args {
command.arg(pysim_arg); command.arg(pysim_arg);
} }
// wait for the child process to stop // execute pySim and wait for it to stop
// let child = command.stdout(Stdio::piped()).spawn().unwrap(); let output = command.output().expect("process failed to execute!");
// let output = child.wait_with_output().unwrap();
let output = command.output().expect("process failed to execute");
if output.status.success() { if output.status.success() {
let output_string = String::from_utf8(output.stdout).unwrap(); let output_string = String::from_utf8(output.stdout).unwrap();
pysim_outputs.push(output_string.clone()); pysim_outputs.push(output_string.clone());
println!("{} ", output_string); println!("{} ", output_string);
println!("{} programmed sim card", "SUCCESSFULLY".green()); println!("{} programmed sim card", "SUCCESSFULLY".green());
} else { } else {
println!("{} ", String::from_utf8(output.stdout).unwrap());
println!("{} ", String::from_utf8(output.stderr).unwrap()); println!("{} ", String::from_utf8(output.stderr).unwrap());
println!("{}, please check the output of pySim above!", "ERROR".red()); println!("{}, please check the output of pySim above!", "ERROR".red());
continue; continue;
@ -107,8 +107,73 @@ fn main() {
print!("{}: The command is not executed since {} is enabled\n", "WARNING".yellow(), "dry_run".yellow()); print!("{}: The command is not executed since {} is enabled\n", "WARNING".yellow(), "dry_run".yellow());
continue; continue;
} }
//TODO: Implement me
println!("{}. Not Implemented Yet!", "TODO".red()); println!("{}. Not Implemented Yet!", "TODO".red());
} }
// add command to be run on the open5gcore
/*
* S = imsi
* k = Ki
* a = 8000 amf
* o = opc/op
* s = sqn (= 0)
* t = auth_type (= 0)
* c = op is opc
* u = usim_type (= 0)
*/
user_provision_commands.push(format!("./provision_user.sh -S {} -k {} -a {} -o {} -s {} -t {} -c {} -u {}",
String::from(&conf.IMSI),
args.ki,
"8000",
{
if args.use_op {
&args.op
} else {
&args.opc
}
},
"0",
"0",
{
if args.use_op {
"0"
} else {
"1"
}
},
"0"
));
/*
* I = imsi
* M = msisdn
* n = default
* u = username, leer lassen -> imsi
* k = Ki
* o = opc/op
* s = sqn wie oben (= 0)
* v = yes
* a = 8000 amf
*/
provision_commands.push(format!("./provision.sh -I {} -M {} -n mnc{}.mcc{}.3gppnetwork.org -k {} -o {} -s {} -v {} -a {}",
conf.IMSI,
format!("49{}", imsi_ending),
args.mnc,
args.mcc,
args.ki,
{
if args.use_op {
&args.op
} else {
&args.opc
}
},
"0",
"yes",
"8000"
));
} }
// output to file // output to file
@ -117,10 +182,15 @@ fn main() {
for pysim_out in pysim_outputs { for pysim_out in pysim_outputs {
writeln!(&mut file, "{}", pysim_out).unwrap(); writeln!(&mut file, "{}", pysim_out).unwrap();
} }
writeln!(&mut file, "\nCommands to be executed on core:").unwrap(); writeln!(&mut file, "\nCommands to be executed on core\nUDM provisioning:").unwrap();
for command in user_provision_commands { for command in user_provision_commands {
writeln!(&mut file, "{}", command).unwrap(); writeln!(&mut file, "{}", command).unwrap();
} }
writeln!(&mut file, "\nHSS provisioning:").unwrap();
for command in provision_commands {
writeln!(&mut file, "{}", command).unwrap();
}
exit_programm(0) exit_programm(0)
} }

View File

@ -9,7 +9,7 @@ use serde::Deserialize;
use crate::CliArgs; use crate::CliArgs;
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug, Clone)]
// disable compiler warnings as this is just a struct to save data as it is in csv data // disable compiler warnings as this is just a struct to save data as it is in csv data
#[allow(dead_code, non_snake_case)] #[allow(dead_code, non_snake_case)]
pub struct CardValues { pub struct CardValues {
@ -34,26 +34,34 @@ pub struct CardValues {
KIK3: String, KIK3: String,
} }
impl CardValues { pub fn get_imsi_ending(card_config: &mut CardValues) -> String {
pub fn generate_pysim_args(self, args: &CliArgs) -> Vec<String> { card_config.IMSI[6..].to_string()
}
pub fn update_imsi(card_config: &mut CardValues, cli_args: &CliArgs) {
card_config.IMSI = format!("{}{}{}",
cli_args.mcc,
cli_args.mnc,
&card_config.IMSI[(cli_args.mnc.len() + cli_args.mcc.len())..]
);
}
pub fn generate_pysim_args(card_config: &CardValues, cli_args: &CliArgs) -> Vec<String> {
// calculate new imsi // calculate new imsi
let new_imsi: &String = &format!("--imsi={}{}{}", let p = format!("-p{}", cli_args.device);
args.mnc, let imsi = format!("--imsi={}", card_config.IMSI);
args.mcc, let name = format!("--name=\"{}\"", cli_args.name);
&self.IMSI[(args.mnc.len() + args.mcc.len())..] let mnc = format!("--mnc={}", cli_args.mnc);
); let mcc = format!("--mcc={}", cli_args.mcc);
let p = format!("-p{}", args.device); let iccid = format!("--iccid={}", card_config.ICCID);
let name = format!("--name=\"{}\"", args.name); let pin_adm = format!("--pin-adm={}", card_config.ADM1);
let mnc = format!("--mnc={}", args.mnc); let ki = format!("--ki={}", cli_args.ki);
let mcc = format!("--mcc={}", args.mcc);
let iccid = format!("--iccid={}", self.ICCID); if cli_args.use_op {
let pin_adm = format!("--pin-adm={}", self.ADM1); let op = format!("--op={}", cli_args.op);
let ki = format!("--ki={}", args.ki);
if args.use_op {
let op = format!("--op={}", args.op);
vec![ vec![
p, p,
new_imsi.to_string(), imsi.to_string(),
name, name,
mnc, mnc,
mcc, mcc,
@ -63,10 +71,10 @@ impl CardValues {
op op
] ]
} else { } else {
let opc = format!("--opc={}", args.opc); let opc = format!("--opc={}", cli_args.opc);
vec![ vec![
p, p,
new_imsi.to_string(), imsi.to_string(),
name, name,
mnc, mnc,
mcc, mcc,
@ -76,18 +84,9 @@ impl CardValues {
opc opc
] ]
} }
}
} }
pub fn parse_csv(path: &str) -> Result<Vec<CardValues>, Box<dyn Error>> { pub fn parse_csv(path: &str) -> Result<Vec<CardValues>, Box<dyn Error>> {
// // Build the CSV reader and iterate over each record.
// let mut rdr = csv::Reader::from_reader(io::stdin());
// let header = rdr.records().next().unwrap().unwrap();
// println!("{:?}", header);
// for result in rdr.records().skip(1) {
// let sim_conf: CardValues = result.unwrap().deserialize(Some(&header)).unwrap();
// println!("{:?}", sim_conf);
// }
if let Ok(mut lines) = read_lines(path) { if let Ok(mut lines) = read_lines(path) {
let first_line = &lines.next().unwrap().unwrap(); let first_line = &lines.next().unwrap().unwrap();
let first_line = first_line.replace(" ", ""); let first_line = first_line.replace(" ", "");