diff --git a/README.md b/README.md
index 5b98ca6..9c07f7c 100644
--- a/README.md
+++ b/README.md
@@ -28,28 +28,28 @@ Aside from docker, which you also need for Bitwarden, BitBetter requires the fol
With your pre-requisites installed, begin the installation of BitBetter by downloading it through Github or using the git command:
```bash
-git clone https://github.com/online-stuff/BitBetter.git
+git clone https://github.com/jakeswenson/BitBetter.git
```
First, we need to add the correct version of Newtonsoft.Json to the license generator and the BitBetter docker directories.
```bash
cd BitBetter/src/licenseGen/
-dotnet add package Newtonsoft.Json --version 11.0.0
+dotnet add package Newtonsoft.Json --version 12.0.1
cd ../bitBetter
-dotnet add package Newtonsoft.Json --version 11.0.0
+dotnet add package Newtonsoft.Json --version 12.0.1
```
## Building BitBetter
-Now that you've set up your build environment, you can run the main `BitBetter/build.sh` script to generate a modified version of the `bitwarden/api` and `bitwarden/identity` docker images.
+Now that you've set up your build environment, you can **run the main build script** to generate a modified version of the `bitwarden/api` and `bitwarden/identity` docker images.
From the BitBetter directory, simply run:
```bash
./build.sh
```
-This will create a new self-signed certificate in the `.keys` directory one does not already exist and then create a modified version of the official `bitwarden/api` called `bitbetter/api` and a modified version of the `bitwarden/identity` called `bitbetter/identity`. You may now simply edit your bitwarden docker-compose.yml to utilize the modified image.
+This will create a new self-signed certificate in the `.keys` directory one does not already exist and then create a modified version of the official `bitwarden/api` called `bitbetter/api` and a modified version of the `bitwarden/identity` called `bitbetter/identity`. You may **now simply edit your bitwarden docker-compose.yml to utilize the modified image**.
Edit your `/path/to/bwdata/docker/docker-compose.yml`.
@@ -61,10 +61,10 @@ You'll also want to edit the `/path/to/bwdata/scripts/run.sh` file. In the `func
> Replace `dockerComposePull`
with `#dockerComposePull`
-You can now start or restart Bitwarden as normal and the modified api will be used. It is now ready to accept self-issued licenses.
+You can now start or restart Bitwarden as normal and the modified api will be used. **It is now ready to accept self-issued licenses.**
---
-**Note: Manually generating Certificate & Key**
+### Note: Manually generating Certificate & Key
If you wish to generate your self-signed cert & key manually, you can run the following commands.
@@ -74,7 +74,7 @@ openssl x509 -inform DER -in cert.cert -out cert.pem
openssl pkcs12 -export -out cert.pfx -inkey key.pem -in cert.pem -passin pass:test -passout pass:test
```
-Note that the password here must be `test`.[1](#f1)
+> Note that the password here must be `test`.[1](#f1)
---
@@ -82,22 +82,41 @@ Note that the password here must be `test`.[1](#f1)
There is a tool included in the directory `src/licenseGen/` that will generate new individual and organization licenses. These licenses will be accepted by the modified Bitwarden because they will be signed by the certificate you generated in earlier steps.
-First, from the `BitBetter/src/licenseGen` directory, build the license generator.[2](#f2)
+First, from the `BitBetter` directory, **build the license generator**.[2](#f2)
```bash
./build.sh
```
-Now, from the `BitBetter/src/licenseGen` directory, you can run the tool to generate licenses.
+In order to run the tool and generate a license you'll need to get a **user's GUID** in order to generate an **invididual license** or the server's **install ID** to generate an **Organization license**. These can be retrieved most easily through the Bitwarden [Admin Portal](https://help.bitwarden.com/article/admin-portal/).
-You'll need to get a user's GUID in order to generate an invididual license and the server's install ID to generate an Organization license. These can be retrieved most easily through the Bitwarden [Admin Portal](https://help.bitwarden.com/article/admin-portal/).
+If you generated your keys in the default `BitBetter/.keys` directory, you can **simply run the license gen in interactive mode** from the `Bitbetter` directory and **follow the prompts to generate your license**.
```bash
-./run.sh ~/BitBetter/.keys/cert.pfx user "Name" "EMail" "User-GUID"
-./run.sh ~/BitBetter/.keys/cert.pfx org "Name" "EMail" "Install-ID used to install the server"
+./src/licenseGen/run.sh interactive
```
-The license generator will spit out a JSON-formatted license which can then be used within the Bitwarden web front-end to license your user or org!
+**The license generator will spit out a JSON-formatted license which can then be used within the Bitwarden web front-end to license your user or org!**
+
+---
+
+### Note: Alternative Ways to Generate License
+
+If you wish to run the license gen from a directory aside from the root `BitBetter` one, you'll have to provide the absolute path to your cert.pfx.
+
+```bash
+./src/licenseGen/run.sh /Absolute/Path/To/BitBetter/.keys/cert.pfx interactive
+```
+
+Additional, instead of interactive mode, you can also pass the parameters directly to the command as follows.
+
+```bash
+./src/licenseGen/run.sh /Absolute/Path/To/BitBetter/.keys/cert.pfx user "Name" "EMail" "User-GUID"
+./src/licenseGen/run.sh /Absolute/Path/To/BitBetter/.keys/cert.pfx org "Name" "EMail" "Install-ID used to install the server"
+```
+
+---
+
# FAQ: Questions (you might have?)
@@ -121,4 +140,4 @@ I'm still in the testing/evaluating phase. If I am hosting the server/data, let
1 If you wish to change this you'll need to change the value that `src/licenseGen/Program.cs` uses for it's `GenerateUserLicense` and `GenerateOrgLicense` calls, but this is really unnecessary as this certificate does not represent any type of security issue.
-2This tool build ontop of the `bitbetter/api` container image so make sure you've built that above using the root `./build.sh` script.
\ No newline at end of file
+2This tool build ontop of the `bitbetter/api` container image so make sure you've built that above using the root `./build.sh` script.
diff --git a/ReadMeInstall b/ReadMeInstall
deleted file mode 100644
index 49265ed..0000000
--- a/ReadMeInstall
+++ /dev/null
@@ -1,95 +0,0 @@
-These are the commands I used (and a few of my notes) for a minimal Debian Stretch install..
-Software Selection - "SSH server" and 'standard system utilities" only
-
-
-
-sudo apt-get update
-sudo apt-get install vim vim-doc vim-scripts wget curl git
-sudo apt-get dist-upgrade
-sudo reboot
-
----The next few lines I setup my server authentication and other misc profile settings you can skip until sudo apt-get
-
-ssh-keygen
-
-echo "ssh-rsa AA...1Q== " >> .ssh/authorized_keys
-
-echo ":set mouse=" >> .vimrc
-echo "set nocompatible" >> .vimrc
-
-vi .bashrc
-
-sudo visudo ---- tom ALL=(ALL) NOPASSWD:ALL
-
-sudo vi /etc/ssh/sshd_config - Enable 'PermitRootLogin prohibit-password' and 'PasswordAuthentication no'
-
-sudo apt-get update
-sudo apt install apt-transport-https ca-certificates curl gnupg2 software-properties-common
-curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -
-sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable"
-sudo apt update
-apt-cache policy docker-ce
-sudo apt install docker-ce
-sudo systemctl status docker
-sudo usermod -aG docker ${USER}
-exit
-
-id -nG
-docker version
-docker info
-docker run hello-world
-
-sudo curl -L --fail https://github.com/docker/compose/releases/download/1.23.1/run.sh -o /usr/local/bin/docker-compose
-sudo chmod +x /usr/local/bin/docker-compose
-
-wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.asc.gpg
-sudo mv microsoft.asc.gpg /etc/apt/trusted.gpg.d/
-wget -q https://packages.microsoft.com/config/debian/9/prod.list
-sudo mv prod.list /etc/apt/sources.list.d/microsoft-prod.list
-sudo chown root:root /etc/apt/trusted.gpg.d/microsoft.asc.gpg
-sudo chown root:root /etc/apt/sources.list.d/microsoft-prod.list
-
-curl -s -o bitwarden.sh https://raw.githubusercontent.com/bitwarden/core/master/scripts/bitwarden.sh && sudo chmod u+x bitwarden.sh
-./bitwarden.sh install
-
-sudo apt-get update
-sudo apt-get install dotnet-sdk-2.1
-
-git clone https://github.com/online-stuff/BitBetter.git
-
-cd BitBetter/src/licenseGen/
-dotnet add package Newtonsoft.Json --version 11.0.0
-
-cd ~/BitBetter/src/bitBetter
-dotnet add package Newtonsoft.Json --version 11.0.0
-
-cd ~/BitBetter/.keys
-rm *
-
-openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.cert -days 36500 -outform DER -passout pass:test
-openssl x509 -inform DER -in cert.cert -out cert.pem
-openssl pkcs12 -export -out cert.pfx -inkey key.pem -in cert.pem -passin pass:test -passout pass:test
-
-
-cd ~/BitBetter
-./build.sh
-
-cd src/licenseGen/
-./build.sh
-
-cd ~
-
-vi ~/bwdata/docker/docker-compose.yml - Change image: bitwarden/api:1.26.0 to image: bitbetter/api and image: bitwarden/identity:x.xx.x to image: bitbetter/identity
-vi ~/bwdata/env/global.override.env - Enter mail__smtp relay settings
-vi ~/bwdata/scripts/run.sh - function restart() { dockerComposePull to #dockerComposePull
-
-./bitwarden start
-
-----Server should be up and running.. Create a user account
-
-cd ~/BitBetter/src/licenseGen/
-./build.sh
-./run.sh ~/BitBetter/.keys/cert.pfx user "Name" "EMail" "User-GUID"
- Get User-GUID from the admin portal of the BitWarden server
-
-./run.sh ~/BitBetter/.keys/cert.pfx org "Name" "EMail" "Install-ID used to install the server from bitwarden.com/host"
diff --git a/src/licenseGen/Program.cs b/src/licenseGen/Program.cs
index 8e0e667..fc1823a 100644
--- a/src/licenseGen/Program.cs
+++ b/src/licenseGen/Program.cs
@@ -33,6 +33,121 @@ namespace bitwardenSelfLicensor
certExists() && coreExists();
}
+ app.Command("interactive", config =>
+ {
+ string buff="", licensetype="", name="", email="", businessname="";
+
+ bool valid_guid = false, valid_installid = false;
+ Guid guid, installid;
+
+ config.OnExecute(() =>
+ {
+ if (!verifyTopOptions())
+ {
+ if (!coreExists()) config.Error.WriteLine($"Cant find core dll at: {coreDll.Value()}");
+ if (!certExists()) config.Error.WriteLine($"Cant find certificate at: {cert.Value()}");
+
+ config.ShowHelp();
+ return 1;
+ }
+
+ WriteLine("Interactive license mode...");
+
+ while (licensetype == "")
+ {
+ WriteLine("What would you like to generate, a [u]ser license or an [o]rg license?");
+ buff = Console.ReadLine();
+
+ if(buff == "u")
+ {
+ licensetype = "user";
+ WriteLineOver("Okay, we will generate a user license.");
+
+ while (valid_guid == false)
+ {
+ WriteLine("Please provide the user's guid — refer to the Readme for details on how to retrieve this. [GUID]:");
+ buff = Console.ReadLine();
+
+ if (Guid.TryParse(buff, out guid))valid_guid = true;
+ else WriteLineOver("The user-guid provided does not appear to be valid.");
+ }
+ }
+ else if (buff == "o")
+ {
+ licensetype = "org";
+ WriteLineOver("Okay, we will generate an organization license.");
+
+ while (valid_installid == false)
+ {
+ WriteLine("Please provide your Bitwarden Install-ID — refer to the Readme for details on how to retrieve this. [Install-ID]:");
+ buff = Console.ReadLine();
+
+ if (Guid.TryParse(buff, out installid)) valid_installid = true;
+ else WriteLineOver("The install-id provided does not appear to be valid.");
+ }
+
+ while (businessname == "")
+ {
+ WriteLineOver("Please enter a business name, default is BitBetter. [Business Name]:");
+ buff = Console.ReadLine();
+ if (buff == "") businessname = "BitBetter";
+ else if (checkBusinessName(buff)) businessname = buff;
+ }
+ }
+ else
+ {
+ WriteLineOver("Unrecognized option \'" + buff + "\'. ");
+ }
+ }
+
+ while (name == "")
+ {
+ WriteLineOver("Please provide the username this license will be registered to. [username]:");
+ buff = Console.ReadLine();
+ if ( checkUsername(buff) ) name = buff;
+ }
+
+ while (email == "")
+ {
+ WriteLineOver("Please provide the email address for the user " + name + ". [email]");
+ buff = Console.ReadLine();
+ if ( checkEmail(buff) ) email = buff;
+ }
+
+
+ if (licensetype == "user")
+ {
+ WriteLineOver("Confirm creation of \"user\" license for username: \"" + name + "\", email: \"" + email + "\", User-GUID: \"" + guid + "\"? Y/n");
+ buff = Console.ReadLine();
+ if ( buff == "" || buff == "y" || buff == "Y" )
+ {
+ GenerateUserLicense(new X509Certificate2(cert.Value(), "test"), coreDll.Value(), name, email, guid, null);
+ }
+ else
+ {
+ WriteLineOver("Exiting...");
+ return 0;
+ }
+ }
+ else if (licensetype == "org")
+ {
+ WriteLineOver("Confirm creation of \"organization\" license for business name: \"" + businessname + "\", username: \"" + name + "\", email: \"" + email + "\", Install-ID: \"" + installid + "\"? Y/n");
+ buff = Console.ReadLine();
+ if ( buff == "" || buff == "y" || buff == "Y" )
+ {
+ GenerateOrgLicense(new X509Certificate2(cert.Value(), "test"), coreDll.Value(), name, email, installid, businessname, null);
+ }
+ else
+ {
+ WriteLineOver("Exiting...");
+ return 0;
+ }
+ }
+
+ return 0;
+ });
+ });
+
app.Command("user", config =>
{
var name = config.Argument("Name", "your name");
@@ -82,6 +197,7 @@ namespace bitwardenSelfLicensor
var name = config.Argument("Name", "your name");
var email = config.Argument("Email", "your email");
var installId = config.Argument("InstallId", "your installation id (GUID)");
+ var businessName = config.Argument("BusinessName", "name For the organization (optional)");
var key = config.Argument("Key", "your key id (optional)");
var help = config.HelpOption("--help | -h | -?");
@@ -118,7 +234,7 @@ namespace bitwardenSelfLicensor
return 1;
}
- GenerateOrgLicense(new X509Certificate2(cert.Value(), "test"), coreDll.Value(), name.Value, email.Value, installationId, key.Value);
+ GenerateOrgLicense(new X509Certificate2(cert.Value(), "test"), coreDll.Value(), name.Value, email.Value, installationId, businessName.Value, key.Value);
return 0;
});
@@ -143,6 +259,49 @@ namespace bitwardenSelfLicensor
}
}
+ // checkUsername Checks that the username is a valid username
+ static bool checkUsername(string s)
+ {
+ if ( string.IsNullOrWhiteSpace(s) ) {
+ WriteLineOver("The username provided doesn't appear to be valid.\n");
+ return false;
+ }
+ return true; // TODO: Actually validate
+ }
+
+ // checkBusinessName Checks that the Business Name is a valid username
+ static bool checkBusinessName(string s)
+ {
+ if ( string.IsNullOrWhiteSpace(s) ) {
+ WriteLineOver("The Business Name provided doesn't appear to be valid.\n");
+ return false;
+ }
+ return true; // TODO: Actually validate
+ }
+
+ // checkEmail Checks that the email address is a valid email address
+ static bool checkEmail(string s)
+ {
+ if ( string.IsNullOrWhiteSpace(s) ) {
+ WriteLineOver("The email provided doesn't appear to be valid.\n");
+ return false;
+ }
+ return true; // TODO: Actually validate
+ }
+
+ // WriteLineOver Writes a new line to console over last line.
+ static void WriteLineOver(string s)
+ {
+ Console.SetCursorPosition(0, Console.CursorTop -1);
+ Console.WriteLine(s);
+ }
+
+ // WriteLine This wrapper is just here so that console writes all look similar.
+ static void WriteLine(string s)
+ {
+ Console.WriteLine(s);
+ }
+
static void GenerateUserLicense(X509Certificate2 cert, string corePath,
string userName, string email, Guid userId, string key)
{
@@ -176,7 +335,7 @@ namespace bitwardenSelfLicensor
}
static void GenerateOrgLicense(X509Certificate2 cert, string corePath,
- string userName, string email, Guid instalId, string key)
+ string userName, string email, Guid instalId, string businessName, string key)
{
var core = AssemblyLoadContext.Default.LoadFromAssemblyPath(corePath);
@@ -194,7 +353,7 @@ namespace bitwardenSelfLicensor
set("Id", Guid.NewGuid());
set("Name", userName);
set("BillingEmail", email);
- set("BusinessName", "BitBetter");
+ set("BusinessName", string.IsNullOrWhiteSpace(businessName) ? "BitBetter" : businessName);
set("Enabled", true);
set("Plan", "Custom");
set("PlanType", (byte)6);
diff --git a/src/licenseGen/licenseGen.csproj b/src/licenseGen/licenseGen.csproj
index a24ae32..73abe54 100644
--- a/src/licenseGen/licenseGen.csproj
+++ b/src/licenseGen/licenseGen.csproj
@@ -7,7 +7,7 @@
-
+
diff --git a/src/licenseGen/run.sh b/src/licenseGen/run.sh
index 3174ade..2219640 100755
--- a/src/licenseGen/run.sh
+++ b/src/licenseGen/run.sh
@@ -2,11 +2,17 @@
script_dir=`cd $(dirname $0); pwd`
+# Grab the absolute path to the default pfx location
+cert_path=`cd ./.keys; ls -d -1 $PWD/cert.pfx`
+
if [ "$#" -lt "1" ]; then
echo "USAGE: $0 [License Gen args...]"
exit 1
+elif [ "$#" -ge "2" ]; then
+ # If a cert path is provided manually, override the default
+ cert_path=$1
+ shift
fi
-cert_path=$1
-shift
+
docker run -it -v "$cert_path:/cert.pfx" bitbetter/licensegen "$@"