From a194b2d888e44087905b3d1bdba818cac07da482 Mon Sep 17 00:00:00 2001 From: Florian Briand Date: Tue, 23 Jul 2024 14:15:06 +0200 Subject: [PATCH] chore: setup sesam-vitale lib with crossplatform ssv usage --- Cargo.lock | 10 +++ crates/sesam-vitale/.env.build.linux.example | 3 + crates/sesam-vitale/.env.build.win.example | 3 + crates/sesam-vitale/.env.linux.example | 2 + crates/sesam-vitale/.env.win.example | 2 + crates/sesam-vitale/.gitignore | 9 ++ crates/sesam-vitale/Cargo.toml | 5 ++ crates/sesam-vitale/README.md | 34 ++++++++ crates/sesam-vitale/build.rs | 31 +++++++ crates/sesam-vitale/lib/.gitkeep | 0 crates/sesam-vitale/lib/ssvw64.lib | Bin 0 -> 2104 bytes crates/sesam-vitale/src/main.rs | 5 ++ crates/sesam-vitale/src/ssvlib_demo.rs | 84 +++++++++++++++++++ crates/sesam-vitale/src/win/fsv/ssvw64.def | 5 ++ scripts/compile_win_headers.bat | 26 ++++++ 15 files changed, 219 insertions(+) create mode 100644 crates/sesam-vitale/.env.build.linux.example create mode 100644 crates/sesam-vitale/.env.build.win.example create mode 100644 crates/sesam-vitale/.env.linux.example create mode 100644 crates/sesam-vitale/.env.win.example create mode 100644 crates/sesam-vitale/.gitignore create mode 100644 crates/sesam-vitale/README.md create mode 100644 crates/sesam-vitale/build.rs create mode 100644 crates/sesam-vitale/lib/.gitkeep create mode 100644 crates/sesam-vitale/lib/ssvw64.lib create mode 100644 crates/sesam-vitale/src/main.rs create mode 100644 crates/sesam-vitale/src/ssvlib_demo.rs create mode 100644 crates/sesam-vitale/src/win/fsv/ssvw64.def create mode 100644 scripts/compile_win_headers.bat diff --git a/Cargo.lock b/Cargo.lock index 648d490..6b98be6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -769,6 +769,12 @@ dependencies = [ "syn 2.0.72", ] +[[package]] +name = "dotenv" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" + [[package]] name = "dpi" version = "0.1.1" @@ -2924,6 +2930,10 @@ dependencies = [ [[package]] name = "sesam-vitale" version = "0.1.0" +dependencies = [ + "dotenv", + "libc", +] [[package]] name = "sha2" diff --git a/crates/sesam-vitale/.env.build.linux.example b/crates/sesam-vitale/.env.build.linux.example new file mode 100644 index 0000000..e7ab058 --- /dev/null +++ b/crates/sesam-vitale/.env.build.linux.example @@ -0,0 +1,3 @@ +SESAM_FSV_VERSION=1.40.13 +SESAM_FSV_LIB_PATH=/opt/santesocial/fsv/${SESAM_FSV_VERSION}/lib +SESAM_FSV_SSVLIB=ssvlux64 diff --git a/crates/sesam-vitale/.env.build.win.example b/crates/sesam-vitale/.env.build.win.example new file mode 100644 index 0000000..872ef1a --- /dev/null +++ b/crates/sesam-vitale/.env.build.win.example @@ -0,0 +1,3 @@ +SESAM_FSV_VERSION=1.40.13 +SESAM_FSV_LIB_PATH="C:/Program Files/santesocial/fsv/${SESAM_FSV_VERSION}/lib" +SESAM_FSV_SSVLIB=ssvw64 diff --git a/crates/sesam-vitale/.env.linux.example b/crates/sesam-vitale/.env.linux.example new file mode 100644 index 0000000..c8d84aa --- /dev/null +++ b/crates/sesam-vitale/.env.linux.example @@ -0,0 +1,2 @@ +SESAM_FSV_VERSION=1.40.13 +SESAM_INI_PATH=/etc/opt/santesocial/fsv/${SESAM_FSV_VERSION}/conf/sesam.ini diff --git a/crates/sesam-vitale/.env.win.example b/crates/sesam-vitale/.env.win.example new file mode 100644 index 0000000..bcd5177 --- /dev/null +++ b/crates/sesam-vitale/.env.win.example @@ -0,0 +1,2 @@ +SESAM_FSV_VERSION=1.40.13 +SESAM_INI_PATH=${ALLUSERSPROFILE}\\santesocial\\fsv\\${SESAM_FSV_VERSION}\\conf\\sesam.ini diff --git a/crates/sesam-vitale/.gitignore b/crates/sesam-vitale/.gitignore new file mode 100644 index 0000000..5c052ec --- /dev/null +++ b/crates/sesam-vitale/.gitignore @@ -0,0 +1,9 @@ +# Ignore Rust target directory +/target + +# Ignore .env files +.env +.env.build + +# Ignore exploitation files - only usefull for local debugging on windows +lib/*.exp diff --git a/crates/sesam-vitale/Cargo.toml b/crates/sesam-vitale/Cargo.toml index 7132546..e62b5db 100644 --- a/crates/sesam-vitale/Cargo.toml +++ b/crates/sesam-vitale/Cargo.toml @@ -4,3 +4,8 @@ version = "0.1.0" edition = "2021" [dependencies] +dotenv = "0.15" +libc = "0.2" + +[build-dependencies] +dotenv = "0.15" diff --git a/crates/sesam-vitale/README.md b/crates/sesam-vitale/README.md new file mode 100644 index 0000000..5638408 --- /dev/null +++ b/crates/sesam-vitale/README.md @@ -0,0 +1,34 @@ +## Requirements + +- Installer le [package FSV](https://industriels.sesam-vitale.fr/group/fournitures-sesam-vitale) + - Les librairies dynamiques (.lib, .dll, ...) fournies ne sont pas installés dans les emplacements standard du système, il faudra donc configurer leur chemin d'installation dans le fichier de configuration `.env.build` (voir ci-dessous) + - Le détail des chemins d'installation est donné dans la documentation du package FSV `fsv-mi-004_pack-FSV1.40.14_V2.3.pdf` + - Linux - par défaut : `/opt/santesocial/fsv/1.40.13/lib` + - Windows - par défaut : `C:\Program Files\santesocial\santesocial\fsv\1.40.14\lib` (ou dans Program Files (x86) si c'est le package 32bits qui a été installé) + +- Installer la [CryptolibCPS](https://industriels.sesam-vitale.fr/group/galss-cryptolib-cps) + - Ce package fourni également l'utilitaire "CPS Gestion" pour obtenir des informations sur le lecteur de carte, etc. + - Linux : `cpgeslux` + - Windows : `...` + +## Setup + +- Créer et éditer le fichier de configuration de build `.env.build` en s'inspirant d'un des fichiers d'exemple (`.env.build.linux.example`, `.env.build.win.example`...) + - Ce fichier est nécessaire pour le build du package Rust +- Créer et éditer le fichier de configuration de l'exécution `.env` en s'inspirant d'un des fichiers d'exemple (`.env.linux.example`, `.env.win.example`...) + - Ce fichier est nécessaire pour l'exécution du package Rust compilé, et doit donc être présent aux côtés de l'exécutable généré, le cas échéant + +## Build + +### Windows - Compilation des headers FSV + +Sous windows, la librairie dynamique fournie par le package FSV nécessite des headers qui ne sont pas présents dans la `.dll`. Il est donc nécessaire de fournir ces headers, en les renseignant dans des fichiers `crates/sesam-vitale/src/win/fsv/*.def` qui seront compilés en leur version binaire `crates/sesam-vitale/lib/*.lib`. + +En cas de modification des fichiers `.def`, pour re-compiler ces headers, faire appel au script `scripts/compile_win_headers.bat`. + +| /!\ Attention, le script `compile_win_headers.bat` exécute, en interne, l'utilitaire `vcvarsall.bat` et le linker `lib.exe` de Visual Studio. Visual Studio doit donc être installé et le chemin vers l'intallation le script `vcvarsall.bat`, écrit en dur dans le script `compile_win_headers.bat` doit être adapté à votre installation. + +## À creuser + +- Compilation cross platform facilitée par du Docker : https://github.com/cross-rs/cross +- Pour éviter l'usage de dotenv pour la configuration, on peut utiliser https://direnv.net/ diff --git a/crates/sesam-vitale/build.rs b/crates/sesam-vitale/build.rs new file mode 100644 index 0000000..15d7c70 --- /dev/null +++ b/crates/sesam-vitale/build.rs @@ -0,0 +1,31 @@ +extern crate dotenv; + +use std::env; +use std::path::PathBuf; + +fn main() { + // Load the .env.build file for build-time environment variables + dotenv::from_filename(".env.build").ok(); + println!("cargo::rerun-if-changed=.env.build"); + + let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); + + // Add local lib directory to the linker search path (for def files and static libs) + let static_lib_path = PathBuf::from(manifest_dir).join("lib"); + println!("cargo::rustc-link-search=native={}", static_lib_path.display()); + + // Add the SESAM_FSV_LIB_PATH to the linker search path + let fsv_lib_path = PathBuf::from(env::var("SESAM_FSV_LIB_PATH").unwrap()); + println!("cargo::rustc-link-search=native={}", fsv_lib_path.display()); + + // Add the SESAM_FSV_LIB_PATH to the PATH environment variable + if cfg!(target_os = "windows") { + let path = env::var("PATH").unwrap_or(String::new()); + println!("cargo:rustc-env=PATH={};{}", fsv_lib_path.display(), path); + } else if cfg!(target_os = "linux") { + println!("cargo:rustc-env=LD_LIBRARY_PATH={}", fsv_lib_path.display()); + } + + // Link the SESAM_FSV_SSVLIB dynamic library + println!("cargo::rustc-link-lib=dylib={}", env::var("SESAM_FSV_SSVLIB").unwrap()); +} diff --git a/crates/sesam-vitale/lib/.gitkeep b/crates/sesam-vitale/lib/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/crates/sesam-vitale/lib/ssvw64.lib b/crates/sesam-vitale/lib/ssvw64.lib new file mode 100644 index 0000000000000000000000000000000000000000..13cbd5a9e64e27005c0cc1330e6d2e10e663592a GIT binary patch literal 2104 zcmcIlPj6B|5dT4eDlrDdgYi$qq>1%{?c+gdV$ACw8%Zf8K)t>K4_Xph8bCdIX*l@_ zyqGj5eg%*H0ET$*=%JsZ2kXq+-S?+bg#Pvq4f@C#Kle^t0fa^eT0|>Q&@Cgt(7jw1-*mFp9XqvgL;&!QGuD>j=m2$<( zcFFAZ-oDG|FwMeFKL6)A-U|hBTzR!q*fiHyDk~_LUz@qZRzIIx)#&Ti!I9|`F_Uj~ z8*9~WzfmlERJ>A0t8>_F?Oj$9!ikYdxyVEanvEdP4gn`&;G6`tSzt($AVUaYL=Zqw z?q>XPIqu0I9A3FQIi4e+az$QfE=h&OtFj@Il(gDyf!4pOM_*QTv>UYsGx+lHQ!^R> zt`R0Yl2)VkW^b-6IKZII2gOKgAhw!pS=D}ZPE$vBX!DKcnH0 zNxKr3KjK9W{yUJB9Fri5v`({U-B`z~5=~!r?igzjw5#N+?HT(wx=Ji@ c_ushort; + fn SSV_LireCartePS(NomRessourcePS: *const c_char, NomRessourceLecteur: *const c_char, CodePorteurPS: *const c_char, ZDonneesSortie: *mut *mut c_void, TTailleDonneesSortie: *mut size_t) -> c_ushort; + fn SSV_LireConfig(ZDonneesSortie: *mut *mut c_void, TTailleDonneesSortie: *mut size_t) -> c_ushort; +} + +fn ssv_init_lib_2() { + let ini_str = env::var("SESAM_INI_PATH").expect("SESAM_INI_PATH must be set"); + let ini = CString::new(ini_str).expect("CString::new failed"); + unsafe { + let result = SSV_InitLIB2(ini.as_ptr()); + println!("SSV_InitLIB2 result: {}", result); + } +} + +fn ssv_lire_carte_ps() { + let resource_ps = CString::new("PS").expect("CString::new failed"); + let resource_reader = CString::new("TRANSPA1").expect("CString::new failed"); + let card_number = CString::new("1234567890").expect("CString::new failed"); + + let mut buffer: *mut c_void = ptr::null_mut(); + let mut size: size_t = 0; + unsafe { + let result = SSV_LireCartePS( + resource_ps.as_ptr(), + resource_reader.as_ptr(), + card_number.as_ptr(), + &mut buffer, + &mut size + ); + println!("SSV_LireCartePS result: {}", result); + + if !buffer.is_null() { + let hex_values = std::slice::from_raw_parts(buffer as *const u8, size); + for &byte in hex_values { + print!("{:02X} ", byte); + } + println!(); + + libc::free(buffer); + } + } +} + +fn ssv_lire_config() { + let mut buffer: *mut c_void = ptr::null_mut(); + let mut size: size_t = 0; + unsafe { + let result = SSV_LireConfig(&mut buffer, &mut size); + println!("SSV_LireConfig result: {}", result); + + if !buffer.is_null() { + let hex_values = std::slice::from_raw_parts(buffer as *const u8, size); + for &byte in hex_values { + print!("{:02X} ", byte); + } + println!(); + + libc::free(buffer); + } + } +} + +pub fn demo() { + dotenv().ok(); + + println!("------- Demo for the SSV library --------"); + + ssv_init_lib_2(); + ssv_lire_carte_ps(); + ssv_lire_config(); + + println!("-----------------------------------------"); +} diff --git a/crates/sesam-vitale/src/win/fsv/ssvw64.def b/crates/sesam-vitale/src/win/fsv/ssvw64.def new file mode 100644 index 0000000..4d66637 --- /dev/null +++ b/crates/sesam-vitale/src/win/fsv/ssvw64.def @@ -0,0 +1,5 @@ +LIBRARY "ssvw64" +EXPORTS + SSV_InitLIB2 + SSV_LireCartePS + SSV_LireConfig diff --git a/scripts/compile_win_headers.bat b/scripts/compile_win_headers.bat new file mode 100644 index 0000000..2bde361 --- /dev/null +++ b/scripts/compile_win_headers.bat @@ -0,0 +1,26 @@ +@echo off +rem Set variables +set LIB_DIR=crates/sesam-vitale/lib +set DEF_DIR=crates/sesam-vitale/src/win/fsv + +if "%1"=="/clean" ( + goto clean +) + +rem Set the environment for the x64 platform +call "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsall.bat" x64 + +rem Create a ssvw64.lib file from the ssvw64.def file +lib /def:ssvw64.def /out:%LIB_DIR%\ssvw64.lib /machine:x64 + +rem Build complete +pause +exit /b 0 + +:clean +del %LIB_DIR%\*.lib +del %LIB_DIR%\*.exp + +rem Clean complete +pause +exit /b 0