openlink-license-reader
Skill42 starsChanged 50 days agoMITView on GitHub
Read and display OpenLink Software license files (.lic) in a beautified, human-readable format. Parses ASN.1 DER-encoded license files using openssl, extracts all license fields, flags expired licenses visually, and supports single-file or directory-wide scanning. Use when the user asks to read, inspect, check, or list OpenLink license files.
- Installs packages
In this repository45 other files it gives its agents.
- agent-rdf-memory/AGENTS.mdAGENTS.md
- AGENTS.mdAGENTS.md
- a2a-clientSkill
- acp-clientSkill
- csv-to-rdf-det-generatorSkill
- data-twinglerSkill
- dbpedia-query-skillSkill
- document-to-kg-skillSkill
- fediverse-crudSkill
- fuxi-engineerSkill
- infographic-describerSkill
- iodbc-dsn-managerSkill
- kg-generatorSkill
- linked-data-skillsSkill
- llm-routing-skillSkill
- monidSkill
- mpp-stripe-clientSkill
- mtls-curlSkill
- opal-agent-skill-assemblerSkill
- openlink-license-managerSkill
- openlink-request-broker-configuratorSkill
- opml-rss-readerSkill
- osdi-inclusion-engineSkill
- pinchtabSkill
- rdf-det-variant-generatorSkill
- rdf-infographic-skillSkill
- resource-access-offers-generatorSkill
- rss-feed-generatorSkill
- s3-query-skillSkill
- screencast-recorderSkill
- set-webdav-resource-propertySkill
- sparql-faceted-browserSkill
- ucp-clientSkill
- uriburner-opal-agent-skillsSkill
- virtuoso-rdf-bulk-loaderSkill
- virtuoso-rdf-loaderSkill
- virtuoso-support-agentSkill
- wc2026-match-reportSkill
- weblog-from-webdavSkill
- website-from-webdavSkill
- wikidata-query-skillSkill
- world-cup-2026-navigatorSkill
- x402-buyerSkill
- xmla-clientSkill
- youidSkill
The file
We split this skill into the rules it gives an agent
10 rules. About 0 are common, 7 are distinctive, and 3 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈7
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 15
Default execution order when REST or remote access is needed:
- Distinctive: line 22
If the user names a specific mode or protocol, follow that preference instead.
- Very specific: line 55
If multiple .lic files are found and no specific file was requested:
- Very specific: line 108
→ Full field reference and decode tables: Read references/asn1-field-map.md
- Distinctive: line 171
When scanning a directory, produce a compact summary table:
- Very specific: line 187
Only show the raw openssl asn1parse output if the user explicitly asks ("show raw", "show dump", "show ASN.1"):
- Distinctive: line 200
Run Step 0 — resolve license file(s)
- Distinctive: line 201
If single file resolved (explicit path or user selection): run Steps 1–2 (full detail)
- Distinctive: line 202
If directory resolved with multiple files: run Step 3 (summary table), then offer to inspect any individual file
- Distinctive: line 203
Always offer: "Show raw ASN.1 dump?" after displaying results
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
OpenLink License Reader Skill
Purpose
Parse and display OpenLink .lic files (ASN.1 DER-encoded) in a clean, human-readable format using openssl asn1parse. Flags expired licenses. Supports single file or full directory scan.
Execution Routing
Default execution order when REST or remote access is needed:
- Local execution — parse license files directly using
openssl asn1parse(primary mode) - URIBurner REST functions — for remote license validation or registry lookups
- Terminal-owned OAuth flow — when a REST endpoint requires OAuth 2.0 authentication, execute the OAuth flow from the terminal (authorization code, client credentials, or device flow), capture the Bearer token, and inject it into subsequent REST/OpenAPI calls via
Authorization: Bearer {token}headers - MCP — if a remote MCP-enabled service exposes license validation tools
If the user names a specific mode or protocol, follow that preference instead.
Step 0 — Locate License File(s)
Resolve the target in this priority order:
| Priority | Source | Detail |
| 1 | Explicit filename | User provides a path — use as-is, skip all other steps |
| 2 | $OPL_LICENSE_DIR | Check env var; scan that directory for *.lic files |
| 3 | OS default path | See table below |
OS Default License Paths
| OS | Default Path |
| macOS | /Library/Application Support/openlink/Licenses |
| Linux | /etc/oplmgr/ |
| Windows | C:\Program Files\OpenLink Software\UDA\bin\ |
# Detect OS
uname -s # Darwin = macOS, Linux = Linux
# Check env var
echo $OPL_LICENSE_DIR
# List license files in resolved directory
ls "/Library/Application Support/openlink/Licenses/"*.lic 2>/dev/nullIf multiple .lic files are found and no specific file was requested:
- Default: scan all and produce a summary table (one row per file)
- On request: inspect a single named file in full detail
Step 1 — Parse the License File
openssl asn1parse -in "{license-file}" -i -inform derDo NOT use
-dumpunless the user explicitly asks to see the raw hex dump.
Parse the output with Python to extract all key-value pairs:
import subprocess, re, sys
from datetime import datetime
def parse_license(filepath):
result = subprocess.run(
['openssl', 'asn1parse', '-in', filepath, '-i', '-inform', 'der'],
capture_output=True, text=True
)
lines = result.stdout.splitlines()
fields = {}
product = None
i = 0
while i < len(lines):
line = lines[i]
# Product name: second PRINTABLESTRING at depth 2, before the fields SEQUENCE
if not product and 'd=2' in line and 'PRINTABLESTRING' in line:
m = re.search(r'PRINTABLESTRING\s+:(.*)', line)
if m:
product = m.group(1).strip()
# Key-value pairs: consecutive PRINTABLESTRING at depth 4
if 'd=4' in line and 'PRINTABLESTRING' in line:
m = re.search(r'PRINTABLESTRING\s+:(.*)', line)
if m:
key = m.group(1).strip()
if i + 1 < len(lines):
next_line = lines[i + 1]
if 'd=4' in next_line and 'PRINTABLESTRING' in next_line:
mv = re.search(r'PRINTABLESTRING\s+:(.*)', next_line)
if mv:
fields[key] = mv.group(1).strip()
i += 2
continue
i += 1
return product, fields→ Full field reference and decode tables: Read references/asn1-field-map.md
Step 2 — Beautified Single-File Output
Present all extracted fields as a formatted table. Apply decode tables from references/asn1-field-map.md for WSType, Availability, Platform, and Modules.
Status Logic
from datetime import datetime
def license_status(expire_date_str):
if not expire_date_str or expire_date_str.strip() == '':
return '**PERPETUAL**'
try:
# Format: "Thu Mar 18 00:00:00 2027 GMT"
dt = datetime.strptime(expire_date_str.strip(), '%a %b %d %H:%M:%S %Y %Z')
if dt < datetime.utcnow():
return '**EXPIRED** ⚠️'
else:
days = (dt - datetime.utcnow()).days
return f'**ACTIVE** (expires in {days} days)'
except Exception:
return expire_date_strOutput Format
## License: virtuoso.lic
| Field | Value |
|--------------------|--------------------------------------------------------------|
| Product | virtuoso |
| Registered To | https://my.openlinksw.com/dataspace/person/kidehen@... |
| Serial Number | GNvyBBRU/MTaRKMt8KlcQC0jdUM= |
| Release | 8.3 |
| Edition | Enterprise (WSType=3) |
| Availability | Enabled |
| Platform | Any (_ANY_) |
| Users | 20 |
| Connections | 20 |
| CPUs | 128 |
| Modules | COLUMNSTORE, CLUSTER, ABAC, BI, REPL, VAL, VDB, SPIN |
| Clients | ODBC, JDBC, OLEDB, DOTNET, XMLA |
| Disable SNBC | Yes |
| Unique ID | B9C96F39D0985C6A002612A5BF503E33 |
| Expire Date | **PERPETUAL** |
Status: **PERPETUAL**For expired licenses, the Status line reads:
Status: **EXPIRED** ⚠️ (expired: Thu Mar 18 00:00:00 2023 GMT)Step 3 — Directory Summary Mode
When scanning a directory, produce a compact summary table:
| File | Product | Registered To | Release | Edition | Connections | Expires | Status |
|-------------------|-----------|----------------------------|---------|------------|-------------|------------------------------|---------------|
| virtuoso.lic | virtuoso | kidehen@openlinksw.com | 8.3 | Enterprise | 20 | Perpetual | **PERPETUAL** |
| oplrqb.lic | oplrqb | OpenLink Internal Use | 10.0 | Enterprise | 100 | Thu Mar 18 00:00:00 2027 GMT | **ACTIVE** |
| oracle19.lic | oracle19 | OpenLink Internal Use | 9.0 | Enterprise | 50 | Thu Mar 18 00:00:00 2023 GMT | **EXPIRED** ⚠️|Sort order: EXPIRED first (to draw attention), then ACTIVE, then PERPETUAL.
Step 4 — Raw Dump (On Request Only)
Only show the raw openssl asn1parse output if the user explicitly asks ("show raw", "show dump", "show ASN.1"):
openssl asn1parse -in "{license-file}" -i -dump -inform derPresent as a fenced code block.
Initialization Sequence
When invoked:
- Run Step 0 — resolve license file(s)
- If single file resolved (explicit path or user selection): run Steps 1–2 (full detail)
- If directory resolved with multiple files: run Step 3 (summary table), then offer to inspect any individual file
- Always offer: "Show raw ASN.1 dump?" after displaying results
Troubleshooting
| Symptom | Cause | Fix |
openssl: command not found | openssl not installed | Install via brew install openssl (macOS) or apt install openssl (Linux) |
unable to load error | File not DER-encoded or corrupted | Verify file is a valid .lic file |
error reading | Wrong path or permissions | Check path and ls -l the file |
| All fields empty | Wrong -inform (try -inform pem) | Try both der and pem |
ExpireDate blank | Perpetual license | Treat as no expiry — display PERPETUAL |
Reference Files
| File | Contents |
references/asn1-field-map.md | All known OpenLink ASN.1 license fields with decode tables for WSType, Availability, Platform, Modules |
references/openssl-asn1parse-guide.md | How to interpret raw openssl asn1parse output; depth/indentation meaning |
Version
1.0.0 — Initial release. Single-file and directory scan modes. ASN.1 DER parsing via openssl. Beautified output with expiry status, edition decode, and module/client lists.
⛔ VERIFY BEFORE DELIVERY: Before returning results to the user, re-read any query templates, output format requirements, or verification steps defined in this skill. Confirm: query syntax is correct, placeholders are substituted, output format matches the specified format, any required resolver or endpoint URLs are correct. Apply the CLAUDE.md Anti-Drift Protocol.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

