A Go client library for interacting with the on-premise license_server. This library provides the necessary tools to securely authenticate, maintain a session, and handle licensed content.
This implementation is designed to be a direct counterpart to the reference C implementation, providing a type-safe and idiomatic Go interface.
- Secret Parsing: Handles both plain-text (
.json) and encrypted (.enc.json) client secret files. - Mutual Authentication: Performs a secure, signature-based handshake with the license server to obtain a session token.
- Session Management: Includes
Keepalive()andRelease()methods to maintain and terminate sessions gracefully. - Secure Verification: Cryptographically verifies server and content signatures to protect against tampering and MITM attacks.
- TLS Flexibility: Provides an option to allow insecure TLS connections for local development against servers with self-signed certificates.
- Typed Errors: Exports a comprehensive set of errors for robust, programmatic error handling.
- Go 1.21 or higher.
You can run the example client directly from the source code without a separate build step using the go run command. The example is located in the cmd/example_client directory.
-
Navigate to the example's directory:
cd cmd/example_client -
Run the program:
The program takes an optional
--allow_insecure_tlsflag, followed by the path to the secret file and an optional password for encrypted files.# Using a plain-text secret go run . /path/to/your/client.json # Using an encrypted secret with a password go run . /path/to/your/client.enc.json "your-password" # Allowing insecure TLS for local development (flag before arguments) go run . --allow_insecure_tls /path/to/your/client.json
To compile the example into a standalone executable, use the go build command.
-
Navigate to the example's directory:
cd cmd/example_client -
Build the executable:
# This will create an executable named 'example_client' (or 'example_client.exe' on Windows) go build .
-
Run the compiled executable:
# On Linux or macOS ./example_client /path/to/your/client.json # On Windows ./example_client.exe /path/to/your/client.json
Below is a basic example of how to import and use the lic_client_go library in your own Go project. It includes the best practice of using a defer statement to ensure the license is released.
package main
import (
"fmt"
"log"
"time"
"lic_client_go" // Assumes the library is in your GOPATH or a local module
)
func main() {
// 1. Initialize the client from a secret file
client, err := lic_client_go.NewLicensingClient("/path/to/your/client.json", "")
if err != nil {
log.Fatalf("Failed to initialize client: %v", err)
}
// Best practice: Defer the release call to ensure the session is terminated
// even if other operations fail later on.
defer func() {
fmt.Println("\nReleasing the session...")
if err := client.Release(); err != nil {
// A failure here is not necessarily critical, but should be logged.
log.Printf("--> FAILED to release session: %v", err)
} else {
fmt.Println("--> SUCCESS: Session released.")
}
}()
fmt.Printf("Successfully parsed secret for client: %s\n", client.GetClientID())
// 2. (Optional) Allow insecure TLS for local development
// client.SetInsecureTLS(true)
// 3. Authenticate with the server
fmt.Println("\nAttempting to authenticate...")
err = client.Authenticate()
if err != nil {
// The deferred Release() will still run
log.Fatalf("--> FAILED to authenticate: %v", err)
}
fmt.Println("--> SUCCESS: Authentication complete!")
fmt.Printf(" Session Token: %s\n", client.GetSessionToken())
if client.GetCustomContent() != "" {
fmt.Printf(" Custom Content: %s\n", client.GetCustomContent())
}
// 4. Send a keepalive to maintain the session
fmt.Println("\nSending keepalive message...")
time.Sleep(2 * time.Second)
err = client.Keepalive()
if err != nil {
log.Printf("--> FAILED to send keepalive: %v", err)
} else {
fmt.Println("--> SUCCESS: Keepalive acknowledged by server.")
}
}The library exports a set of typed errors, allowing you to use errors.Is() to programmatically check for specific failure conditions.
| Error Variable | Description |
|---|---|
ErrSecurity |
A critical security verification failed, such as a bad signature from the server. |
ErrNetwork |
A failure in network communication (e.g., DNS, TCP, request failed). |
ErrServerResponse |
The server returned a response that was unexpected, unhandled, or could not be parsed. |
ErrBadPassword |
An incorrect password was used for an encrypted file, or the file is corrupt. |
ErrNotAuthenticated |
An operation was attempted that requires a session, but the client is not authenticated. |
ErrInvalidSecretFile |
The secret file is invalid, empty, or unreadable. |
ErrJSONParse |
Data that was expected to be JSON was malformed. |
ErrJSONStructure |
A parsed JSON object is missing required fields. |
ErrKeyParse |
A cryptographic key within the secret file is malformed. |
ErrFileNotFound |
The secret file could not be found at the given path. |
ErrLicensesInUse |
All available license slots for the client are currently in use. |
ErrRateLimited |
The client is being rate-limited by the server or an intermediary proxy. |
ErrForbidden |
The server is refusing to fulfill the request due to a policy violation (e.g., expired license). |
ErrInternalServer |
The server encountered an unexpected, internal error (HTTP 500). |
ErrServiceUnavailable |
The server is temporarily unable to handle the request (HTTP 503). |