From 0e0a2f533d55b5b7bdae4a5cc3b8bf11c474ab40 Mon Sep 17 00:00:00 2001 From: Bart Jablonski Date: Thu, 27 Jul 2023 11:08:23 +0200 Subject: [PATCH] The GSM package [ver. 0.21.0] The GSM package [ver. 0.21.0] Changes: - new debugging parameter `encrypt` added to the `%GSM()` macro - annoying note on "automatic type conversion" fixed --- README.md | 2 +- gsm.md | 17 ++- gsm.zip | Bin 17604 -> 17742 bytes hist/0.21.0/gsm.md | 329 ++++++++++++++++++++++++++++++++++++++++++++ hist/0.21.0/gsm.zip | Bin 0 -> 17742 bytes 5 files changed, 342 insertions(+), 6 deletions(-) create mode 100644 hist/0.21.0/gsm.md create mode 100644 hist/0.21.0/gsm.zip diff --git a/README.md b/README.md index c3f7a1f..b3b86a8 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ to create secured macros stored in SAS Proc FCMP functions. The dataset with functions can be shared between different operating systems and allows to generate macros on site without showing their code. -SHA256 digest for the latest version of `GSM`: F*91C619E47EFAB44CCEB8B892BA1D7A8F9948590DA1317B8EA330F5D12642CE0E +SHA256 digest for the latest version of `GSM`: F*56DC0DCCE06B4281BF3FA6FA3875CBA87772BDA7FAB601B06740A7980FFB0E07 [**Documentation for GSM**](./gsm.md "Documentation for GSM") diff --git a/gsm.md b/gsm.md index 311c7a8..3564c17 100644 --- a/gsm.md +++ b/gsm.md @@ -8,7 +8,7 @@ --- -# The GSM package [ver. 0.20.5] ############################################### +# The GSM package [ver. 0.21.0] ############################################### The **GSM** (a.k.a. *Generate Secure Macros*) package allows to create secured macros stored in SAS Proc FCMP functions. @@ -91,10 +91,10 @@ Package contains: Required SAS Components: `Base SAS Software` -*SAS package generated by generatePackage, version 20230411* +*SAS package generated by generatePackage, version 20230520* The SHA256 hash digest for package GSM: -`F*91C619E47EFAB44CCEB8B892BA1D7A8F9948590DA1317B8EA330F5D12642CE0E` +`F*56DC0DCCE06B4281BF3FA6FA3875CBA87772BDA7FAB601B06740A7980FFB0E07` ## >>> `%GSM()` macro: <<< ####################### @@ -143,6 +143,7 @@ The basic syntax is the following, the `<...>` means optional parameters: <,encodingRestricted=> <,secret=> <,lineEnd=> + <,encrypt=> ) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -182,10 +183,16 @@ The basic syntax is the following, the `<...>` means optional parameters: `0A` for line feed, `0D` for carriage return, `0D0A` for both, and `20` for space. +* `encrypt=` - *Optional*, the default value is `ENCRYPT`. + Indicate if `FCMP` functions generated by the package + are encrypted. Value has to be either empty or `ENCRYPT`, + all other are converted to default. The option is + dedicated for debugging, keep the default value + for production use. + * `trim=` - *Deprecated*, the default value is `0`. *Kept for backward compatibility.* - - + --- ### Example: ################################################################### diff --git a/gsm.zip b/gsm.zip index 8c313cfe47999edff649ded4456d82accf47a6cb..f5610a663d609c752fce296230cb7587f92a2efd 100644 GIT binary patch delta 14203 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 AP5=M^ delta 13929 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 Z{{V;p0Mh^1EO3I*CD@@+ME~9W{{Ukmy?X!v diff --git a/hist/0.21.0/gsm.md b/hist/0.21.0/gsm.md new file mode 100644 index 0000000..3564c17 --- /dev/null +++ b/hist/0.21.0/gsm.md @@ -0,0 +1,329 @@ +- [The GSM package](#gsm-package) +- [Content description](#content-description) + * [`%GSM()` macro](#gsm-macro) + * [`%GSMpck_makeFCMPcode()` macro](#gsmpck-makefcmpcode-macro) + + * [License](#license) + +--- + + +# The GSM package [ver. 0.21.0] ############################################### + +The **GSM** (a.k.a. *Generate Secure Macros*) package allows +to create secured macros stored in SAS Proc FCMP functions. +The dataset with functions can be shared and allows to generate +macros without showing their code. + +The GSM package is basically an automated version of the following: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +proc fcmp outlib = work.gsm.secure ENCRYPT; + function generateMacro() $; + rc = RESOLVE(' + %macro secretMacro(x) / SECURE; + data test; + a = "&x."; + run; + %mend; + '); + return (rc); + endsub; +run; + +/* share work.gsm dataset */ +options cmplib = work.gsm; +data _null_; + rc = generateMacro(); + put rc=; +run; + +/* enjoy */ +%secretMacro(42) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +See examples for more details. + +Recording of presentation with "how it works" description, in Polish, is avaliable [here](https://www.youtube.com/watch?v=LtaWPe2sgRY&t=1s). + +*How to use it:* + - Copy all files with your secured macros code into a directory. + Best approach is to have one file for one macro. + - Copy a path to the directory. + - Run the following code: + ``` + %GSM(, cmplib=) + ``` + - Share generated `ZIP` file (unzip and run the code). + +**Limitations:** + - Single macro file cannot be longer than 32760 bytes. + + - Multiline text variable. Consider the following code text file: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +%macro~test()/SECURE;~#@ +data~test;~#@ +a~=~"abc~#@ +~#@ +def";~#@ +put~a~hex20.;~#@ +run;~#@ +%mend~test;~#@ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +where `~` symbols the space character, +`#` symbols the carriage return (`0D`), +and `@` symbols the line feed (`0A`). +The code file is scanned and inserted into +the `resolve()` function argument in a "byte by byte" +fashion hence also the "end of line" characters are included. +As the result value of variable `a` will be: + +`a = "abc~#@~#@def"`. + +If you want to use the `GSM` package avoid +such "style" of coding in your macros. + + +--- + +Package contains: + 1. macro gsm + 2. macro gsmpck_makefcmpcode + +Required SAS Components: + `Base SAS Software` + +*SAS package generated by generatePackage, version 20230520* + +The SHA256 hash digest for package GSM: +`F*56DC0DCCE06B4281BF3FA6FA3875CBA87772BDA7FAB601B06740A7980FFB0E07` + + +## >>> `%GSM()` macro: <<< ####################### + +The `%GSM()` macro is the main macro of +the **GSM** (a.k.a. *Generate Secure Macros*) package. + +It converts a list of macros provided by the user into +a data set of the Proc FCMP functions. The macros are stored +in functions are encrypted which allow to share them without +showing their code. *Important* thing is that macros provided +by the user *has* to be "secure", i.e. the `secure` option has to +be added to the macro definition. See the example: + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%macro secretMacro(x) / SECURE; /* <- the secure option */ + <... some code ...> +%mend secretMacro; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +As a result a zip file, containing dataset with functions and +code to be executed on site, is generated. + +Since encrypted code is stored in a SAS dataset it has +no limitation in sharing between operating systems (like catalogs have). + +*Limitation:* Due to the `Resolve()` function limitations + a single macro file cannot be longer than 32760 bytes. + +*Notes:* +- All macros have to have the `secure` option added, i.e. `%macro aMacroname(...) / SECURE ;`. +- During the execution a test macro, named `%GSMpck_dummyMacroForTests()`, is generated. +- The `%GSM()` macro calls the `%GSMpck_makeFCMPcode(...)` macro internally. + +### SYNTAX: ################################################################### + +The basic syntax is the following, the `<...>` means optional parameters: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%GSM( + path + <,trim=0> + <,cmplib=work.generateMacros> + <,source2=> + <,outpath=> + <,encodingRestricted=> + <,secret=> + <,lineEnd=> + <,encrypt=> +) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**Arguments description**: + +1. `path` - *Required*, indicates a directory which contains files with macros. + Only files with `sas` extension are used. + +* `cmplib=` - *Optional*, the default value is `work.generateMacros`. + Names the dataset which will contain generated functions. + +* `source2=` - *Optional*, the default value is null. + Indicate if `%includ`-ed files are printed out. + Any value other than null enables printing. + +* `outpath=` - *Optional*, the default value is set the same as the `path`. + Points a directory in which a result (a zip file) is generated. + +* `encodingRestricted=` - *Optional*, the default value is `0`. + If set to 1 then if User session encoding is different from + encoding of the session which generates the dataset then + the generateMacros() function will not execute macro code. + +* `secret=` - *Optional*, the default value is null, in such case the + secret is generated from the `sha256(datetime(), hex32.)` function + and is printed in the log. When not null then should be + alphanumerical constant. Non-alphanumerical characters are removed. + Required to execute the `resolve()` function. + User who do not know the value will not be able + to run the `_maxro_XX_()` function. + +* `lineEnd=` - *Optional*, the default value is `0D0A`, indicates which of: + line feed, carriage return, or both, or a space be inserted + at the end of line in the intermediate code file that is generated. + Value has to be hexadecimal code (_NOT_ null), + since the value is resolved as `"&lineEnd."x`, so use e.g. + `0A` for line feed, `0D` for carriage return, + `0D0A` for both, and `20` for space. + +* `encrypt=` - *Optional*, the default value is `ENCRYPT`. + Indicate if `FCMP` functions generated by the package + are encrypted. Value has to be either empty or `ENCRYPT`, + all other are converted to default. The option is + dedicated for debugging, keep the default value + for production use. + +* `trim=` - *Deprecated*, the default value is `0`. + *Kept for backward compatibility.* + +--- + +### Example: ################################################################### + +Example 1. Prepare 2 files: `f1.sas` and `f2.sas` and use the `%GSM()` macro. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%let path = %sysfunc(pathname(work))/path2files; + +%put &=path.; +options dlcreatedir; +libname path "&path."; +filename path "&path."; + +data _null_; + file path(f1.sas); + input; + put _infile_; +cards4; +%macro abc(x) / SECURE; + data test; + do i = 1 to &x.; + put i=; + end; + run; +%mend; +;;;; +run; + +data _null_; + file path(f2.sas); + input; + put _infile_; +cards4; +%macro xyz(x) / SECURE; + %do i = 1 %to &x.; + %put &=i; + %end; +%mend; +;;;; +run; + +%GSM(&path., cmplib=work.myMacros) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +## >>> `%GSMpck_makeFCMPcode()` macro: <<< ####################### + +The `%GSMpck_makeFCMPcode()` macro is an internal macro of +the **GSM** (a.k.a. *Generate Secure Macros*) package. + +It executes a process of converting +a macro provided by the user into +a Proc FCMP function. + +Since encrypted code is stored in a SAS dataset it has +no limitation in sharing between operating systems (like catalogs have). + +*Limitation:* Single macro file cannot be longer than 32760 bytes. + +### SYNTAX: ################################################################### + +The basic syntax is the following, the `<...>` means optional parameters: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%GSMpck_makeFCMPcode( + path + ,number + <,outlib=work.generateMacros.secure> + <,source2=> + <,fileNameCode=FNC> + <,secret=123456789> + <,lineEnd=0A> +) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**Arguments description**: + +1. `path` - *Required*, indicates a directory which contains files with macros. + Only files with `sas` extension are used. + +2. `number` - *Required*, a sequential number. + + +* `cmplib=` - *Optional*, the default value is `work.generateMacros`. + Names the dataset which will contain generated functions. + +* `source2=` - *Optional*, the default value is null. + Indicate if `%includ`-ed files are printed out. + Any value other than null enables printing. + +* `fileNameCode=` - *Optional*, the default value is `FNC`. + Internal fileref. + +* `secret=` - *Optional*, internal, the default value is `1234567890`. + Alphanumerical constant required to execute the `resolve()` + function. User who do not know the value will not be able + to run the `_maxro_XX_()` function. + +* `lineEnd=` - *Optional*, the default value is `0D0A`, indicates which of: + line feed, carriage return, or both, or a space be inserted + at the end of line in the intermediate code file that is generated. + Value has to be hexadecimal code (_NOT_ null), + since the value is resolved as `"&lineEnd."x`, so use e.g. + `0A` for line feed, `0D` for carriage return, + `0D0A` for both, and `20` for space. + +* `trim=` - *Deprecated*, the default value is `0`. + *Kept for backward compatibility.* + +--- + + +## License #################################################################### + +Copyright (c) Bartosz Jablonski, since 2021 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +--- diff --git a/hist/0.21.0/gsm.zip b/hist/0.21.0/gsm.zip new file mode 100644 index 0000000000000000000000000000000000000000..f5610a663d609c752fce296230cb7587f92a2efd GIT binary patch literal 17742 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 GKs*55$JUhq literal 0 HcmV?d00001