]>
description | CLI to WebAPI |
last change | Tue, 28 Jan 2025 22:45:56 +0000 (17:45 -0500) |
Easily transform as many CLI programs as you wish into web APIs.
Please click the tree
link at the top and navigate to
the bin
folder and download the following file to get the
source code for the simulator.
rosado-source-base.zip
To compile it, navigate to the folder it installed within and run the following commands within that folder.
mkdir rosado
mv *rosado-source-base.zip rosado
cd rosado
unzip *rosado-source-base.zip
make
You can also use make install
after running
make
to install it.
Note that this project relies on the CryptoFoleo project for cryptography. Please install that library first before trying to compile this one.
To convert a CLI program to a web API, it must be designed such that it takes in its input as standard input and provides its output as standard output.
This project expects a MySQL/MariaDB installation with a schema titled RosadoAPI. The first time the program is executed, it will automatically create the necessary tables within this schema. Make sure that the password to login to the database is stored as the first line of text in the configuration file in the path below. The second line is used to set the port number.
/etc/rosado-api.conf
The API uses two tables. The first table is ServiceInfo
which is used to set up a CLI program to be used as an API. Below is the
structure for this table.
> describe ServiceInfo;
MariaDB [RosadoAPI]+------------+---------+------+-----+---------+----------------+
Type | Null | Key | Default | Extra |
| Field | +------------+---------+------+-----+---------+----------------+
id | int(11) | NO | PRI | NULL | auto_increment |
| NULL | |
| service | text | YES | | NULL | |
| path | text | YES | | parameters | text | YES | | NULL | |
| +------------+---------+------+-----+---------+----------------+
The service
field is the name of the service and also
corresponds to the path that must be pinged to access it. For example,
if the service is named myapi
and hosted at
localhost
then to access this service, the client will need
to ping localhost/myapi
.
The path
field is the actual full path of the executable
program. The parameters
field is any command line
parameters that should be passed into the program when it is called.
The second table is the AuthInfo
table. This is related
to authentication for users trying to ping the API. Below is the
structure for this table.
> describe AuthInfo;
MariaDB [RosadoAPI]+----------+---------+------+-----+---------+----------------+
Type | Null | Key | Default | Extra |
| Field | +----------+---------+------+-----+---------+----------------+
id | int(11) | NO | PRI | NULL | auto_increment |
| NULL | |
| service | text | YES | | NULL | |
| username | text | YES | | NULL | |
| authkey | text | YES | | timeout | int(11) | YES | | NULL | |
| +----------+---------+------+-----+---------+----------------+
The service
field must correspond to a
service
in the ServiceInfo
table. The
username
field is the name of a registered user allowed to
access an API. The authkey
is their authentication token
which is also used for encryption and decryption. The
timeout
value is how long the user is able to run an
application for. Different users can be authorized to run programs for
longer periods of time.
To generate a unique authkey
for a user, use the command
below.
openssl rand -hex 32
Communication with the API service is encrypted with ChaCha20-HMAC-SHA256 This means it cannot be pinged using plaintext. To ping it and get a response, the request must be encrypted in this way, and the response also must be decrypted in the same way.
Below are variables that will need to be populated in order to ping the API service.
$addr
: The address of the server to send the request
to.$srvc
: The service to send a request to.$user
: The user requesting the service.$auth
: The authentication key.$rqst
: The request data.$sess
: A session identifier.Below is the beginnings of a Bash script defining these values grabbing most from command line arguments except for the request itself which comes from standard input as well as the session ID which is randomly generated.
addr=$1
srvc=$2
user=$3
auth=$4
read rqst
sess=$(openssl rand -hex 12)
The next step is to generate the request data which is computed simply by taking the plaintext request and encrypting it with ChaCha20 using the authentication key. Then, a digest will also need to be computed for the message which allows the server to verify the message has not been tampered with. This must be calculated from the encrypted data using HMAC-SHA256. Both of these values also need to be encoded as base64. Below is a Bash script that generates the encrypted data and digest for the request.
data=$(echo -n "$rqst" | openssl enc -chacha20 -K $auth -iv 00000000$sess | base64 | tr -d '\n')
dgst=$(echo -n "$data" | base64 -d | openssl sha256 -hex -mac HMAC -macopt hexkey:$auth | cut -d '=' -f 2 | xargs)
The username, session, data, and digest then can be combined to form
the post request in application/x-www-form-urlencoded
format. Below is an example of how to produce such a request and store
the response in variable in Bash.
resp=$(curl -s -X POST -d "user=$user&sess=$sess&dgst=$dgst&data=$data" "$addr/$srvc")
The response from the server is in a similar format, so it should first be parsed into different response variables.
for param in user sess dgst data
do
eval r$param=$(echo "$resp" | sed -e "s/.*$param=//" -e "s/&.*//") 2> /dev/null
done
The response message needs to be validated by recomputing the digest and verifying it matches the received digest and verifying the user matches the requested user.
if [ "$user" != "$ruser" ]
then
echo "Invalid response: user mismatch."
exit 1
fi
dgst=$(echo -n "$rdata" | base64 -d | openssl sha256 -hex -mac HMAC -macopt hexkey:$auth | cut -d '=' -f 2 | xargs)
if [ "$dgst" != "$rdgst" ]
then
echo "Invalid response: digest mismatch."
exit 1
fi
Finally, once the response is received and verified, it can be decrypted using ChaCha20. ChaCha20 uses the same command to encrypt as it does to decrypt because it is a symmetrical cipher.
echo -n "$rdata" | base64 -d | openssl enc -d -chacha20 -K $auth -iv 00000000$rsess
Please click the tree
button on the top left of the page
and click the ping.sh
file to see this complete Bash
script.
If you click tree
on the top left of ths page and
navigate into the www
folder there is a file titled
rosado-api.min.js
which can be used to ping a RosadoAPI
server from a web page. When the RosadoAPI server is running, navigating
to its root directory in the browser will show a web page for sending
API requests to the server. The web page uses this JavaScript file.
Below is an example of how to make a request to a RosadoAPI server using the library.
.username = {username};
RosadoAPI.apikey = {authkey};
RosadoAPI.endpoint = {address} + "/" + {service};
RosadoAPI.request(rqst).then(x =>
RosadoAPI
{if (x.success && x.response.trim().length > 0)
{//successful: results in x.response
}else if (x.response.trim().length == 0)
{//empty response
}else
{//error: x.response contains error code
}; })
2 months ago | master | shortlog | log | tree |