diff --git a/README.md b/README.md index 130bf4f..7ded320 100644 --- a/README.md +++ b/README.md @@ -9,14 +9,20 @@ _Beware! BitBetter does janky stuff to rewrite the bitwarden core dll and allow Credit to https://github.com/h44z/BitBetter and https://github.com/jakeswenson/BitBetter # Table of Contents -1. [Getting Started](#getting-started) - + [Dependencies](#dependencies) - + [Setting up BitBetter](#setting-up-bitbetter) - + [Building BitBetter](#building-bitbetter) - + [Updating Bitwarden and BitBetter](#updating-bitwarden-and-bitbetter) - + [Generating Signed Licenses](#generating-signed-licenses) -2. [FAQ](#faq-questions-you-might-have-) -3. [Footnotes](#footnotes) +- [BitBetter](#bitbetter) +- [Table of Contents](#table-of-contents) +- [Getting Started](#getting-started) + - [Dependencies](#dependencies) + - [Setting up BitBetter](#setting-up-bitbetter) + - [Building BitBetter](#building-bitbetter) + - [Note: Manually generating Certificate & Key](#note-manually-generating-certificate--key) + - [Updating Bitwarden and BitBetter](#updating-bitwarden-and-bitbetter) + - [Generating Signed Licenses](#generating-signed-licenses) + - [Note: Alternative Ways to Generate License](#note-alternative-ways-to-generate-license) +- [FAQ: Questions you might have.](#faq-questions-you-might-have) + - [Why build a license generator for open source software?](#why-build-a-license-generator-for-open-source-software) + - [Shouldn't you have reached out to Bitwarden to ask them for alternative licensing structures?](#shouldnt-you-have-reached-out-to-bitwarden-to-ask-them-for-alternative-licensing-structures) +- [Footnotes](#footnotes) # Getting Started The following instructions are for unix-based systems (Linux, BSD, macOS), it is possible to use a Windows systems assuming you are able to enable and install [WSL](https://docs.microsoft.com/en-us/windows/wsl/install-win10). @@ -131,8 +137,8 @@ If you wish to run the license gen from a directory aside from the root `BitBett 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" +./src/licenseGen/run.sh /Absolute/Path/To/BitBetter/.keys/cert.pfx user "Name" "E-Mail" "User-GUID" ["Storage Space in GB"] ["Custom LicenseKey"] +./src/licenseGen/run.sh /Absolute/Path/To/BitBetter/.keys/cert.pfx org "Name" "E-Mail" "Install-ID used to install the server" ["Storage Space in GB"] ["Custom LicenseKey"] ``` --- diff --git a/src/licenseGen/Program.cs b/src/licenseGen/Program.cs index c2ec51d..db395f0 100644 --- a/src/licenseGen/Program.cs +++ b/src/licenseGen/Program.cs @@ -167,7 +167,7 @@ namespace bitwardenSelfLicensor var name = config.Argument("Name", "your name"); var email = config.Argument("Email", "your email"); var userIdArg = config.Argument("User ID", "your user id"); - var storage = config.Argument("Storage", "Extra storage space in GB. Maximum is " + short.MaxValue + " (optional)"); + var storage = config.Argument("Storage", "extra storage space in GB. Maximum is " + short.MaxValue + " (optional, default = max)"); var key = config.Argument("Key", "your key id (optional)"); var help = config.HelpOption("--help | -h | -?"); @@ -201,16 +201,20 @@ namespace bitwardenSelfLicensor return 1; } - if (double.Parse(storage.Value) > short.MaxValue || - double.Parse(storage.Value) < 0 || - string.IsNullOrWhiteSpace(storage.Value)) + short storageShort = 0; + if (!string.IsNullOrWhiteSpace(storage.Value)) { - config.Error.WriteLine("The storage value provided is outside the accepted range of [0-" + short.MaxValue + "]"); - config.ShowHelp("org"); - return 1; + var parsedStorage = double.Parse(storage.Value); + if (parsedStorage > short.MaxValue || parsedStorage < 0) + { + config.Error.WriteLine("The storage value provided is outside the accepted range of [0-" + short.MaxValue + "]"); + config.ShowHelp("org"); + return 1; + } + storageShort = (short) parsedStorage; } - GenerateUserLicense(new X509Certificate2(cert.Value(), "test"), coreDll.Value(), name.Value, email.Value, short.Parse(storage.Value), userId, key.Value); + GenerateUserLicense(new X509Certificate2(cert.Value(), "test"), coreDll.Value(), name.Value, email.Value, storageShort, userId, key.Value); return 0; }); @@ -220,8 +224,8 @@ 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 storage = config.Argument("Storage", "Extra storage space in GB. Maximum is " + short.MaxValue + " (optional)"); - var businessName = config.Argument("BusinessName", "name For the organization (optional)"); + var storage = config.Argument("Storage", "extra storage space in GB. Maximum is " + short.MaxValue + " (optional, default = max)"); + 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 | -?"); @@ -258,16 +262,20 @@ namespace bitwardenSelfLicensor return 1; } - if (double.Parse(storage.Value) > short.MaxValue || - double.Parse(storage.Value) < 0 || - string.IsNullOrWhiteSpace(storage.Value)) + short storageShort = 0; + if (!string.IsNullOrWhiteSpace(storage.Value)) { - config.Error.WriteLine("The storage value provided is outside the accepted range of [0-" + short.MaxValue + "]"); - config.ShowHelp("org"); - return 1; + var parsedStorage = double.Parse(storage.Value); + if (parsedStorage > short.MaxValue || parsedStorage < 0) + { + config.Error.WriteLine("The storage value provided is outside the accepted range of [0-" + short.MaxValue + "]"); + config.ShowHelp("org"); + return 1; + } + storageShort = (short) parsedStorage; } - GenerateOrgLicense(new X509Certificate2(cert.Value(), "test"), coreDll.Value(), name.Value, email.Value, short.Parse(storage.Value), installationId, businessName.Value, key.Value); + GenerateOrgLicense(new X509Certificate2(cert.Value(), "test"), coreDll.Value(), name.Value, email.Value, storageShort, installationId, businessName.Value, key.Value); return 0; }); @@ -356,6 +364,7 @@ namespace bitwardenSelfLicensor var core = AssemblyLoadContext.Default.LoadFromAssemblyPath(corePath); var type = core.GetType("Bit.Core.Models.Business.UserLicense"); + var licenseTypeEnum = core.GetType("Bit.Core.Enums.LicenseType"); var license = Activator.CreateInstance(type); @@ -368,13 +377,14 @@ namespace bitwardenSelfLicensor set("Id", userId); set("Name", userName); set("Email", email); - set("MaxStorageGb", storage); set("Premium", true); + set("MaxStorageGb", storage == 0 ? short.MaxValue : storage); set("Version", 1); set("Issued", DateTime.UtcNow); set("Refresh", DateTime.UtcNow.AddYears(100).AddMonths(-1)); set("Expires", DateTime.UtcNow.AddYears(100)); set("Trial", false); + set("LicenseType", Enum.Parse(licenseTypeEnum, "User")); set("Hash", Convert.ToBase64String((byte[])type.GetMethod("ComputeHash").Invoke(license, new object[0]))); set("Signature", Convert.ToBase64String((byte[])type.GetMethod("Sign").Invoke(license, new object[] { cert }))); @@ -387,6 +397,8 @@ namespace bitwardenSelfLicensor var core = AssemblyLoadContext.Default.LoadFromAssemblyPath(corePath); var type = core.GetType("Bit.Core.Models.Business.OrganizationLicense"); + var licenseTypeEnum = core.GetType("Bit.Core.Enums.LicenseType"); + var planTypeEnum = core.GetType("Bit.Core.Enums.PlanType"); var license = Activator.CreateInstance(type); @@ -403,25 +415,29 @@ namespace bitwardenSelfLicensor set("BusinessName", string.IsNullOrWhiteSpace(businessName) ? "BitBetter" : businessName); set("Enabled", true); set("Plan", "Custom"); - set("PlanType", (byte)6); - set("Seats", (int)32767); + set("PlanType", Enum.Parse(planTypeEnum, "Custom")); + set("Seats", (int)short.MaxValue); set("MaxCollections", short.MaxValue); set("UsePolicies", true); set("UseSso", true); + set("UseKeyConnector", true); + //set("UseScim", true); // available in version 10, which is not released yet set("UseGroups", true); set("UseEvents", true); set("UseDirectory", true); set("UseTotp", true); set("Use2fa", true); - set("MaxStorageGb", storage); + set("UseApi", true); + set("UseResetPassword", true); + set("MaxStorageGb", storage == 0 ? short.MaxValue : storage); set("SelfHost", true); set("UsersGetPremium", true); - set("Version", 6); + set("Version", 9); set("Issued", DateTime.UtcNow); set("Refresh", DateTime.UtcNow.AddYears(100).AddMonths(-1)); set("Expires", DateTime.UtcNow.AddYears(100)); set("Trial", false); - set("UseApi", true); + set("LicenseType", Enum.Parse(licenseTypeEnum, "Organization")); set("Hash", Convert.ToBase64String((byte[])type.GetMethod("ComputeHash").Invoke(license, new object[0]))); set("Signature", Convert.ToBase64String((byte[])type.GetMethod("Sign").Invoke(license, new object[] { cert }))); diff --git a/src/licenseGen/run.sh b/src/licenseGen/run.sh index 6ea9662..ba504c2 100755 --- a/src/licenseGen/run.sh +++ b/src/licenseGen/run.sh @@ -6,14 +6,21 @@ DIR=`exec 2>/dev/null;(cd -- "$DIR") && cd -- "$DIR"|| cd "$DIR"; unset PWD; /us # Grab the absolute path to the default pfx location cert_path="$DIR/../../.keys/cert.pfx" -if [ "$#" -lt "1" ]; then - echo "USAGE: $0 [License Gen args...]" +if [ "$#" -lt "2" ]; then + echo "USAGE: $0 [License Gen args...]" + echo "ACTIONS:" + echo " interactive" + echo " user" + echo " org" exit 1 -elif [ "$#" -ge "2" ]; then - # If a cert path is provided manually, override the default - cert_path="$1" - shift fi -docker run -it --rm -v "$cert_path:/cert.pfx" bitbetter/licensegen "$@" +cert_path="$1" +action="$2" +shift +if [ $action = "interactive" ]; then + docker run -it --rm -v "$cert_path:/cert.pfx" bitbetter/licensegen "$@" +else + docker run --rm -v "$cert_path:/cert.pfx" bitbetter/licensegen "$@" +fi