| src | ||
| build.sh | ||
| LICENSE | ||
| Makefile | ||
| README.md | ||
| README_old.md | ||
RosadoAPI
Easily transform as many CLI programs as you wish into web APIs.
Compilation
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.
Usage
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.
MariaDB [RosadoAPI]> describe ServiceInfo;
+------------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+---------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| service | text | YES | | NULL | |
| path | text | YES | | NULL | |
| 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.
MariaDB [RosadoAPI]> describe AuthInfo;
+----------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+---------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| service | text | YES | | NULL | |
| username | text | YES | | NULL | |
| authkey | text | YES | | NULL | |
| 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.
JavaScript API
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.
RosadoAPI.username = {username};
RosadoAPI.apikey = {authkey};
RosadoAPI.endpoint = {address} + "/" + {service};
RosadoAPI.request(rqst).then(x =>
{
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
}
});