licentivo-launch 0.1.7 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +9 -5
  3. data/lib/licentivo_launch/vendor/licentivo.rb +1 -1
  4. data/lib/licentivo_launch.rb +25 -4
  5. data/vendor/VERSION +1 -1
  6. data/vendor/c/feature_tasks.h +90 -9
  7. data/vendor/c/licentivo.c +2 -2
  8. metadata +1 -119
  9. data/vendor/curl/COPYING.txt +0 -22
  10. data/vendor/curl/bin/libcurl-x64.dll +0 -0
  11. data/vendor/curl/include/brotli/decode.h +0 -409
  12. data/vendor/curl/include/brotli/encode.h +0 -505
  13. data/vendor/curl/include/brotli/port.h +0 -302
  14. data/vendor/curl/include/brotli/shared_dictionary.h +0 -100
  15. data/vendor/curl/include/brotli/types.h +0 -83
  16. data/vendor/curl/include/curl/curl.h +0 -3373
  17. data/vendor/curl/include/curl/curlver.h +0 -77
  18. data/vendor/curl/include/curl/easy.h +0 -123
  19. data/vendor/curl/include/curl/header.h +0 -74
  20. data/vendor/curl/include/curl/mprintf.h +0 -85
  21. data/vendor/curl/include/curl/multi.h +0 -560
  22. data/vendor/curl/include/curl/options.h +0 -70
  23. data/vendor/curl/include/curl/stdcheaders.h +0 -35
  24. data/vendor/curl/include/curl/system.h +0 -399
  25. data/vendor/curl/include/curl/typecheck-gcc.h +0 -964
  26. data/vendor/curl/include/curl/urlapi.h +0 -156
  27. data/vendor/curl/include/curl/websockets.h +0 -98
  28. data/vendor/curl/include/libpsl.h +0 -207
  29. data/vendor/curl/include/libssh2.h +0 -1516
  30. data/vendor/curl/include/libssh2_publickey.h +0 -128
  31. data/vendor/curl/include/libssh2_sftp.h +0 -382
  32. data/vendor/curl/include/nghttp2/nghttp2.h +0 -6878
  33. data/vendor/curl/include/nghttp2/nghttp2ver.h +0 -42
  34. data/vendor/curl/include/nghttp3/nghttp3.h +0 -3704
  35. data/vendor/curl/include/nghttp3/version.h +0 -46
  36. data/vendor/curl/include/ngtcp2/ngtcp2.h +0 -7485
  37. data/vendor/curl/include/ngtcp2/ngtcp2_crypto.h +0 -1071
  38. data/vendor/curl/include/ngtcp2/ngtcp2_crypto_quictls.h +0 -147
  39. data/vendor/curl/include/ngtcp2/version.h +0 -51
  40. data/vendor/curl/include/openssl/aes.h +0 -120
  41. data/vendor/curl/include/openssl/asn1.h +0 -1121
  42. data/vendor/curl/include/openssl/asn1t.h +0 -996
  43. data/vendor/curl/include/openssl/bio.h +0 -716
  44. data/vendor/curl/include/openssl/blowfish.h +0 -106
  45. data/vendor/curl/include/openssl/bn.h +0 -480
  46. data/vendor/curl/include/openssl/buffer.h +0 -102
  47. data/vendor/curl/include/openssl/camellia.h +0 -121
  48. data/vendor/curl/include/openssl/cast.h +0 -99
  49. data/vendor/curl/include/openssl/chacha.h +0 -54
  50. data/vendor/curl/include/openssl/cmac.h +0 -81
  51. data/vendor/curl/include/openssl/cms.h +0 -541
  52. data/vendor/curl/include/openssl/comp.h +0 -7
  53. data/vendor/curl/include/openssl/conf.h +0 -189
  54. data/vendor/curl/include/openssl/crypto.h +0 -458
  55. data/vendor/curl/include/openssl/ct.h +0 -567
  56. data/vendor/curl/include/openssl/curve25519.h +0 -104
  57. data/vendor/curl/include/openssl/des.h +0 -215
  58. data/vendor/curl/include/openssl/dh.h +0 -245
  59. data/vendor/curl/include/openssl/dsa.h +0 -263
  60. data/vendor/curl/include/openssl/dtls1.h +0 -107
  61. data/vendor/curl/include/openssl/ec.h +0 -675
  62. data/vendor/curl/include/openssl/ecdh.h +0 -6
  63. data/vendor/curl/include/openssl/ecdsa.h +0 -6
  64. data/vendor/curl/include/openssl/engine.h +0 -215
  65. data/vendor/curl/include/openssl/err.h +0 -325
  66. data/vendor/curl/include/openssl/evp.h +0 -1288
  67. data/vendor/curl/include/openssl/hkdf.h +0 -65
  68. data/vendor/curl/include/openssl/hmac.h +0 -101
  69. data/vendor/curl/include/openssl/idea.h +0 -99
  70. data/vendor/curl/include/openssl/kdf.h +0 -137
  71. data/vendor/curl/include/openssl/lhash.h +0 -179
  72. data/vendor/curl/include/openssl/md4.h +0 -105
  73. data/vendor/curl/include/openssl/md5.h +0 -99
  74. data/vendor/curl/include/openssl/mlkem.h +0 -236
  75. data/vendor/curl/include/openssl/modes.h +0 -118
  76. data/vendor/curl/include/openssl/obj_mac.h +0 -4646
  77. data/vendor/curl/include/openssl/objects.h +0 -137
  78. data/vendor/curl/include/openssl/ocsp.h +0 -484
  79. data/vendor/curl/include/openssl/opensslconf.h +0 -16
  80. data/vendor/curl/include/openssl/opensslfeatures.h +0 -153
  81. data/vendor/curl/include/openssl/opensslv.h +0 -18
  82. data/vendor/curl/include/openssl/ossl_typ.h +0 -196
  83. data/vendor/curl/include/openssl/pem.h +0 -542
  84. data/vendor/curl/include/openssl/pkcs12.h +0 -284
  85. data/vendor/curl/include/openssl/pkcs7.h +0 -523
  86. data/vendor/curl/include/openssl/poly1305.h +0 -45
  87. data/vendor/curl/include/openssl/posix_time.h +0 -54
  88. data/vendor/curl/include/openssl/rand.h +0 -118
  89. data/vendor/curl/include/openssl/rc2.h +0 -101
  90. data/vendor/curl/include/openssl/rc4.h +0 -88
  91. data/vendor/curl/include/openssl/ripemd.h +0 -107
  92. data/vendor/curl/include/openssl/rsa.h +0 -603
  93. data/vendor/curl/include/openssl/safestack.h +0 -1739
  94. data/vendor/curl/include/openssl/sha.h +0 -190
  95. data/vendor/curl/include/openssl/sm3.h +0 -49
  96. data/vendor/curl/include/openssl/sm4.h +0 -47
  97. data/vendor/curl/include/openssl/srtp.h +0 -148
  98. data/vendor/curl/include/openssl/ssl.h +0 -2336
  99. data/vendor/curl/include/openssl/ssl3.h +0 -441
  100. data/vendor/curl/include/openssl/stack.h +0 -99
  101. data/vendor/curl/include/openssl/tls1.h +0 -764
  102. data/vendor/curl/include/openssl/ts.h +0 -660
  103. data/vendor/curl/include/openssl/txt_db.h +0 -112
  104. data/vendor/curl/include/openssl/ui.h +0 -397
  105. data/vendor/curl/include/openssl/x509.h +0 -1037
  106. data/vendor/curl/include/openssl/x509_vfy.h +0 -464
  107. data/vendor/curl/include/openssl/x509v3.h +0 -1039
  108. data/vendor/curl/include/zconf.h +0 -206
  109. data/vendor/curl/include/zdict.h +0 -481
  110. data/vendor/curl/include/zlib.h +0 -1859
  111. data/vendor/curl/include/zlib_name_mangling.h +0 -8
  112. data/vendor/curl/include/zstd.h +0 -3198
  113. data/vendor/curl/include/zstd_errors.h +0 -107
  114. data/vendor/curl/lib/libcurl.dll.a +0 -0
  115. data/vendor/curl/licenses/brotli/LICENSE.txt +0 -19
  116. data/vendor/curl/licenses/certdata/LICENSE.url +0 -2
  117. data/vendor/curl/licenses/libpsl/COPYING.txt +0 -20
  118. data/vendor/curl/licenses/libressl/COPYING.txt +0 -133
  119. data/vendor/curl/licenses/libssh2/COPYING.txt +0 -43
  120. data/vendor/curl/licenses/nghttp2/COPYING.txt +0 -23
  121. data/vendor/curl/licenses/nghttp3/COPYING.txt +0 -22
  122. data/vendor/curl/licenses/ngtcp2/COPYING.txt +0 -22
  123. data/vendor/curl/licenses/psl/LICENSE.txt +0 -373
  124. data/vendor/curl/licenses/trurl/COPYING.txt +0 -22
  125. data/vendor/curl/licenses/zlibng/LICENSE.md +0 -19
  126. data/vendor/curl/licenses/zstd/LICENSE.txt +0 -30
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aea598de906732fd1f3741dc1b6851c4e52e74189bdb21d543ac5ad5d930eb4e
4
- data.tar.gz: 6af202bc71b6de164c3b7c64a15962466af933bcf8d456536d7645a6a6933cc0
3
+ metadata.gz: 51b7637f7abdae666634cbd1d1fe1861f7531d88c52933269a8cbe3ca0ce10cf
4
+ data.tar.gz: 0123b22169e307ab1775949495045c7033578ebd76ae60a0911df888b33608ac
5
5
  SHA512:
6
- metadata.gz: 4092a1bb39dcbce94382154873c190d378a16bf72e26faafffae040bd6ef053cdf8bf22085111bfc9480aa75fa1ec8a9330a9807f8fa417fde1c037415489f15
7
- data.tar.gz: 603590ca85eae7c6affb1cb8ad88d38c87cade481de25b291e1d02774b338bb7a1ac28fdef20f131918a88ab513f9496bca154953fbc2cdfca11057f08ade6c3
6
+ metadata.gz: 7f7c984c6f50ec39e4f859c743906fc41f795c415ce3770b193709e9469bb60b7b7de68a1d4ca6b70e77acf35f807aa1d7295475babe9609d0d7ecdabb5aedc4
7
+ data.tar.gz: 2c312238790b048985dce8e9da6b279f94637637aa218291d8f537297ebceadf37b4914785b1602bdd1ee502b06f3a03d82afb9f54970ee2ba9527405ae00a47
data/README.md CHANGED
@@ -1,16 +1,16 @@
1
- # Launch Ruby 0.1.7
1
+ # Launch Ruby 0.1.8
2
2
 
3
3
  [Website](https://www.licentivo.com/en/launch.html) · [Documentation](https://www.licentivo.com/en/launch-docs.html) · [Source code](https://github.com/spf86/licentivo-launch-sdk)
4
4
 
5
- > Local account-exchange changes are unpublished. Login uses a short-lived identity assertion; Launch calculates purchased dates and Licentivo owns runtime permission. See the repository guide docs/account-purchase-boundary.md.
5
+ > This README describes the current account-exchange source: Launch package 0.1.8 with embedded official SDK 0.11.8, paired with Launch server 0.3.6-beta. Login obtains a short-lived identity assertion; Licentivo owns runtime permission. Check [backend requirements, migration and release evidence](https://github.com/spf86/licentivo-launch-sdk/blob/main/docs/sdk-compatibility.md) and the [account boundary](https://github.com/spf86/licentivo-launch-sdk/blob/main/docs/account-purchase-boundary.md). A public version number alone does not certify uncommitted local changes.
6
6
 
7
7
  Ruby 3.1+. Install only the Launch gem matching the platform:
8
8
 
9
9
  ```sh
10
- gem install licentivo-launch --version 0.1.7
10
+ gem install licentivo-launch --version 0.1.8
11
11
  ```
12
12
 
13
- SDK 0.11.7 Ruby code, its private native core and Windows curl DLL are included. RubyGems resolves the ordinary base64 dependency. The generic source gem builds its own embedded core automatically and needs normal C11/curl/OpenSSL tools for the platform. No official SDK gem or external native-library override is needed.
13
+ SDK 0.11.8 Ruby code, its private native core and Windows curl DLL are included. RubyGems resolves the ordinary base64 dependency. The generic source gem builds its own embedded core automatically and needs normal C11/curl/OpenSSL tools for the platform. No official SDK gem or external native-library override is needed.
14
14
 
15
15
  ## Direct initialization and manual lifecycle
16
16
 
@@ -40,7 +40,7 @@ Manual development is supported without AI. The combined source bundle includes
40
40
 
41
41
 
42
42
  <!-- account-store-ownership-2026-10-24 -->
43
- ## Local account logout and session ownership (unpublished)
43
+ ## Local account logout and session ownership
44
44
 
45
45
  Account logout tasks use a separate key in the configured secure store. Custom stores must support multiple opaque keys, atomic value replacement and isolation to the current OS user and host. Account lifecycle operations are coordinated across local instances/processes, independently of the licensing cache directory.
46
46
 
@@ -53,3 +53,7 @@ An old instance only changes its own account record and logout task. Repeating a
53
53
  The merchant address selects HTTP or HTTPS; failed HTTPS requests never downgrade to HTTP. For an HTTP customer test server, the customer must enable HTTP on the specific Licentivo API key and enable **Allow SDK HTTP (test environment only)** in their own Launch website/security settings. Use `sandbox` and the explicit client option `Application.connect(..., environment: 'sandbox', allow_http: true)`. The generated test integration code includes it after successful checks. `live` requires HTTPS. Old SDK versions must be upgraded; server switches cannot update compiled client URLs. No access to Licentivo’s private network is needed.
54
54
 
55
55
  See the [setup, failure and HTTPS migration guide in 14 languages](../../docs/http-testing/README.md) ([简体中文](../../docs/http-testing.zh-CN.md)). HTTP does not encrypt credentials; use dedicated test data.
56
+
57
+ ## Metered business tasks
58
+
59
+ The started Application exposes metered execution and interrupted-task settlement. Use a stable job ID, preserve SDK journals, and check the real business outcome before resolving. Ordinary feature calls do not settle quantity. See [the nine-language API and recovery contract](../../docs/metered-feature-tasks.md). Verify the exact installed artifact includes these APIs; this source does not imply that a public package was republished.
@@ -4,7 +4,7 @@ require 'json'
4
4
  require 'monitor'
5
5
 
6
6
  module Licentivo
7
- VERSION = '0.11.7'
7
+ VERSION = '0.11.8'
8
8
 
9
9
  class Error < StandardError
10
10
  attr_reader :code, :http_status, :request_id, :retryable, :retry_after_seconds
@@ -11,7 +11,7 @@ require 'time'
11
11
  require 'monitor'
12
12
 
13
13
  module LicentivoLaunch
14
- VERSION = '0.1.7'
14
+ VERSION = '0.1.8'
15
15
  LIMIT = 1 << 20
16
16
  UUID = /\A[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}\z/
17
17
  class Error < StandardError
@@ -165,7 +165,7 @@ module LicentivoLaunch
165
165
  @store, @transport = store, transport || LicentivoLaunch.method(:default_transport)
166
166
  @factory = runtime_factory || lambda do |config|
167
167
  require_relative 'licentivo_launch/vendor/licentivo'
168
- raise Error.new('SDK_VERSION_MISMATCH') unless Licentivo::VERSION == '0.11.7'
168
+ raise Error.new('SDK_VERSION_MISMATCH') unless Licentivo::VERSION == '0.11.8'
169
169
  Licentivo::Client.new(config)
170
170
  end
171
171
  @root = File.expand_path(cache_dir || File.join(Dir.home, '.cache', 'LicentivoLaunch'))
@@ -240,6 +240,26 @@ module LicentivoLaunch
240
240
  end
241
241
  end
242
242
  end
243
+ def run_metered_feature(feature, quantity, operation_id, &action)
244
+ serial do
245
+ raise Error.new('LOGIN_REQUIRED') unless @runtime
246
+ raise Error.new('METERING_UNSUPPORTED') unless @runtime.respond_to?(:run_metered_feature)
247
+ @runtime.run_metered_feature(feature, quantity, operation_id) do
248
+ begin
249
+ @in_callback = true; action.call
250
+ ensure
251
+ @in_callback = false
252
+ end
253
+ end
254
+ end
255
+ end
256
+ def resolve_metered_feature(operation_id, succeeded)
257
+ serial do
258
+ raise Error.new('LOGIN_REQUIRED') unless @runtime
259
+ raise Error.new('METERING_UNSUPPORTED') unless @runtime.respond_to?(:resolve_metered_feature)
260
+ @runtime.resolve_metered_feature(operation_id, succeeded)
261
+ end
262
+ end
243
263
  def logout(cancellation: nil)
244
264
  account_serial(true) { if @account_cleared && !@record; retry_other_accounts(nil,cancellation);true;else;logout_internal(cancellation);end }
245
265
  end
@@ -344,8 +364,9 @@ module LicentivoLaunch
344
364
  begin
345
365
  runtime.start; cancellation&.check!; @runtime = runtime; @account_cleared=false
346
366
  { user: JSON.parse(JSON.generate(@record['user'])), expires_at: @record['expires_at'] }
347
- rescue StandardError
348
- runtime.close; raise
367
+ rescue StandardError
368
+ begin; runtime.close; rescue StandardError; end
369
+ raise
349
370
  end
350
371
  end
351
372
  def stop
data/vendor/VERSION CHANGED
@@ -1 +1 @@
1
- 0.11.7
1
+ 0.11.8
@@ -44,12 +44,35 @@ static void task_leave(ln_client*c){view_lock(c);c->task_busy=0;view_unlock(c);}
44
44
  static char*task_path(ln_client*c,const char*id){
45
45
  if(!id||!id[0]||strlen(id)>80)return NULL;
46
46
  for(const unsigned char*p=(const unsigned char*)id;*p;p++)if(*p<33||*p>126)return NULL;
47
- char source[65],digest[65],input[256];lock(c);
48
- const char*key=text(c->cfg,"license_key");int ok=key&&key[0]?hash(key,source):text(c->auth,"source_hash")!=NULL;
49
- if(ok&&(!key||!key[0]))snprintf(source,sizeof(source),"%s",text(c->auth,"source_hash"));unlock(c);
47
+ char source[65],digest[65],legacy_digest[65],input[256];lock(c);
48
+ int ok=source_hash(c,source);const char*connection=text(c->cfg,"launch_connection_id");
49
+ if(!ok){unlock(c);return NULL;}
50
+ if(ok){snprintf(input,sizeof(input),"%s\n%s",source,id);ok=hash(input,legacy_digest);}
51
+ if(connection&&connection[0]){
52
+ cJSON*claims=cache_valid(c)?claims_from(c->cached):NULL;
53
+ const char*origin=text(c->cfg,"base_url"),*product=text(claims,"product_id"),*license=text(claims,"license_id"),*dev=text(claims,"device_id");
54
+ ok=claims&&origin&&product&&license&&dev;
55
+ if(ok){size_t size=strlen(origin)+strlen(product)+strlen(license)+strlen(dev)+32;char*scope=malloc(size);ok=scope!=NULL;if(ok){snprintf(scope,size,"LicentivoTask/v2\n%s\n%s\n%s\n%s",origin,product,license,dev);ok=hash(scope,source);free(scope);}}
56
+ cJSON_Delete(claims);
57
+ }
58
+ unlock(c);
50
59
  if(!ok)return NULL;snprintf(input,sizeof(input),"%s\n%s",source,id);if(!hash(input,digest))return NULL;
51
60
  const char*cache=text(c->cfg,"cache_path");if(!cache)return NULL;
52
- char*path=malloc(strlen(cache)+78);if(path)sprintf(path,"%s.task-%s.json",cache,digest);return path;
61
+ char*path=malloc(strlen(cache)+78);if(!path)return NULL;sprintf(path,"%s.task-%s.json",cache,digest);
62
+ if(strcmp(digest,legacy_digest)){
63
+ struct stat info;if(stat(path,&info)!=0&&errno==ENOENT){
64
+ char*legacy=malloc(strlen(cache)+78);if(!legacy){free(path);return NULL;}sprintf(legacy,"%s.task-%s.json",cache,legacy_digest);
65
+ if(stat(legacy,&info)==0){
66
+ #ifdef _WIN32
67
+ ok=state_windows_move(legacy,path);
68
+ #else
69
+ ok=rename(legacy,path)==0;
70
+ #endif
71
+ }else ok=errno==ENOENT;
72
+ free(legacy);if(!ok){free(path);return NULL;}
73
+ }
74
+ }
75
+ return path;
53
76
  }
54
77
  static cJSON*task_read(const char*path,const char*id){
55
78
  struct stat info;if(stat(path,&info)==0){if(info.st_size>4096)return NULL;char*raw=readfile(path,4096);cJSON*task=raw?ln_json(raw):NULL;free(raw);int64_t version;
@@ -68,10 +91,66 @@ static int task_finish(ln_client*c,const char*path,cJSON*task,int succeeded){
68
91
  if(!ok)return task_error(c,"RESERVATION_CLOSED");task_state(task,expected);
69
92
  return write_state(path,task)?1:task_error(c,"TASK_JOURNAL_ERROR");
70
93
  }
94
+ /* Renew only the original reservation. The worker owns no business callback
95
+ * and never changes the task journal or decides the business outcome. */
96
+ typedef struct {
97
+ ln_client*client;const char*feature,*operation,*reservation;int64_t quantity;double deadline;int started;
98
+ #ifdef _WIN32
99
+ HANDLE thread,event;
100
+ #else
101
+ pthread_t thread;pthread_mutex_t mutex;pthread_cond_t condition;int stop;
102
+ #endif
103
+ } task_renewal;
104
+ static int task_renewal_wait(task_renewal*r,double seconds){
105
+ #ifdef _WIN32
106
+ return WaitForSingleObject(r->event,(DWORD)(seconds*1000))==WAIT_TIMEOUT;
107
+ #else
108
+ struct timespec until;clock_gettime(CLOCK_REALTIME,&until);int64_t nanos=(int64_t)(seconds*1e9)+until.tv_nsec;until.tv_sec+=(time_t)(nanos/1000000000);until.tv_nsec=(long)(nanos%1000000000);
109
+ pthread_mutex_lock(&r->mutex);int result=0;while(!r->stop&&result!=ETIMEDOUT)result=pthread_cond_timedwait(&r->condition,&r->mutex,&until);int active=!r->stop;pthread_mutex_unlock(&r->mutex);return active;
110
+ #endif
111
+ }
112
+ #ifdef _WIN32
113
+ static DWORD WINAPI task_renewal_run(LPVOID argument){
114
+ #else
115
+ static void*task_renewal_run(void*argument){
116
+ #endif
117
+ task_renewal*r=argument;double until=r->deadline,interval=60;
118
+ for(;;){
119
+ double remaining=until-task_wall_time();if(remaining<=0)break;double delay=remaining/3;if(delay<.01)delay=.01;if(delay>interval)delay=interval;
120
+ if(!task_renewal_wait(r,delay))break;
121
+ char*raw=ln_reserve(r->client,r->feature,r->quantity,r->operation);cJSON*hold=raw?ln_json(raw):NULL;ln_free_string(raw);
122
+ if(!hold){interval=5;continue;}
123
+ const char*status=text(hold,"status"),*id=text(hold,"reservation_id"),*operation=text(hold,"operation_id");double renewed;
124
+ int valid=status&&!strcmp(status,"pending")&&id&&!strcmp(id,r->reservation)&&operation&&!strcmp(operation,r->operation)&&task_deadline(text(hold,"expires_at"),&renewed);
125
+ cJSON_Delete(hold);if(!valid)break;until=renewed;interval=60;
126
+ }
127
+ return 0;
128
+ }
129
+ static int task_renewal_start(task_renewal*r,ln_client*c,cJSON*task,double deadline){
130
+ r->client=c;r->feature=text(task,"feature");r->operation=text(task,"operation_id");r->reservation=text(task,"reservation_id");num(task,"quantity",&r->quantity);r->deadline=deadline;
131
+ #ifdef _WIN32
132
+ r->event=CreateEventW(NULL,TRUE,FALSE,NULL);if(!r->event)return 0;
133
+ r->thread=CreateThread(NULL,0,task_renewal_run,r,0,NULL);if(!r->thread){CloseHandle(r->event);return 0;}
134
+ #else
135
+ if(pthread_mutex_init(&r->mutex,NULL))return 0;
136
+ if(pthread_cond_init(&r->condition,NULL)){pthread_mutex_destroy(&r->mutex);return 0;}
137
+ if(pthread_create(&r->thread,NULL,task_renewal_run,r)){pthread_cond_destroy(&r->condition);pthread_mutex_destroy(&r->mutex);return 0;}
138
+ #endif
139
+ r->started=1;return 1;
140
+ }
141
+ static void task_renewal_stop(task_renewal*r){
142
+ if(!r->started)return;
143
+ #ifdef _WIN32
144
+ SetEvent(r->event);WaitForSingleObject(r->thread,INFINITE);CloseHandle(r->thread);CloseHandle(r->event);
145
+ #else
146
+ pthread_mutex_lock(&r->mutex);r->stop=1;pthread_cond_signal(&r->condition);pthread_mutex_unlock(&r->mutex);pthread_join(r->thread,NULL);pthread_cond_destroy(&r->condition);pthread_mutex_destroy(&r->mutex);
147
+ #endif
148
+ r->started=0;
149
+ }
71
150
  int ln_run_metered_feature(ln_client*c,const char*feature,int64_t quantity,const char*id,ln_feature_action action,void*context){
72
151
  if(!c||!feature||!action||quantity<=0)return c?task_error(c,"TASK_INPUT_INVALID"):0;
73
152
  if(!task_enter(c))return task_error(c,"TASK_BUSY");
74
- int ok=0;char*path=task_path(c,id);cJSON*task=path?task_read(path,id):NULL;
153
+ task_renewal renewal={0};int ok=0;char*path=task_path(c,id);cJSON*task=path?task_read(path,id):NULL;
75
154
  if(!task){task_error(c,"TASK_JOURNAL_ERROR");goto done;}
76
155
  const char*state=text(task,"state");
77
156
  if(state[0]){int64_t old_quantity;if(!text(task,"feature")||strcmp(text(task,"feature"),feature)||!num(task,"quantity",&old_quantity)||old_quantity!=quantity){task_error(c,"OPERATION_ID_CONFLICT");goto done;}}
@@ -92,14 +171,16 @@ int ln_run_metered_feature(ln_client*c,const char*feature,int64_t quantity,const
92
171
  cJSON_ReplaceItemInObjectCaseSensitive(task,"reservation_id",cJSON_CreateString(text(hold,"reservation_id")));cJSON_Delete(hold);task_state(task,"business_running");
93
172
  if(!write_state(path,task)){raw=ln_cancel(c,text(task,"reservation_id"),id);ln_free_string(raw);task_error(c,"TASK_JOURNAL_ERROR");goto done;}
94
173
  int allowed=ln_check_feature(c,feature),unexpired=valid_deadline&&deadline>task_wall_time();
95
- if(!allowed||!unexpired||!action(context)){
96
- const char*failure=!allowed?"FEATURE_NOT_ENTITLED":!unexpired?"RESERVATION_EXPIRED":"BUSINESS_ACTION_FAILED";
97
- task_state(task,"cancel_pending");if(write_state(path,task))task_finish(c,path,task,0);task_error(c,failure);goto done;
174
+ int renewing=allowed&&unexpired&&task_renewal_start(&renewal,c,task,deadline);
175
+ if(!renewing||!action(context)){
176
+ const char*failure=!allowed?"FEATURE_NOT_ENTITLED":!unexpired?"RESERVATION_EXPIRED":!renewing?"RESERVATION_RENEWAL_UNAVAILABLE":"BUSINESS_ACTION_FAILED";
177
+ task_state(task,"cancel_pending");int saved=write_state(path,task);task_renewal_stop(&renewal);if(saved)task_finish(c,path,task,0);task_error(c,failure);goto done;
98
178
  }
99
179
  task_state(task,"commit_pending");if(!write_state(path,task)){task_error(c,"BUSINESS_COMPLETED_JOURNAL_ERROR");goto done;}
180
+ task_renewal_stop(&renewal);
100
181
  ok=task_finish(c,path,task,1);
101
182
  done:
102
- cJSON_Delete(task);free(path);task_leave(c);return ok;
183
+ task_renewal_stop(&renewal);cJSON_Delete(task);free(path);task_leave(c);return ok;
103
184
  }
104
185
  int ln_resolve_metered_feature(ln_client*c,const char*id,int succeeded){
105
186
  if(!c)return 0;if(!task_enter(c))return task_error(c,"TASK_BUSY");
data/vendor/c/licentivo.c CHANGED
@@ -166,7 +166,7 @@ static int advanced_claims(const cJSON*c){
166
166
  if(get(x,"app_version")&&!app_version(text(x,"app_version")))return 0;
167
167
  if(!num(c,"issued_at",&issued)||!num(c,"expires_at",&expires))return 0;
168
168
  const cJSON*policy=get(c,"runtime_policy");int64_t heartbeat=0;if(!strcmp(model,"floating")&&(!uuid(text(x,"session_id"))||session<=issued||expires>session||!num(policy,"heartbeat_seconds",&heartbeat)||heartbeat==0||!strcmp(text(policy,"offline_mode")?text(policy,"offline_mode"):"","permanent")))return 0;
169
- if(get(x,"launch_connection_id")||get(x,"environment")||get(x,"binding_version")){int64_t binding=0,h=0,o=0;const char*env=text(x,"environment"),*mode=text(policy,"offline_mode");if(!uuid(text(x,"launch_connection_id"))||!env||(strcmp(env,"live")&&strcmp(env,"sandbox"))||!num(x,"binding_version",&binding)||binding<1||strcmp(model,"node_locked")||!uuid(text(x,"session_id"))||session<=issued||expires>session||!num(policy,"heartbeat_seconds",&h)||h<600||!mode||!strcmp(mode,"permanent")||!num(policy,"offline_seconds",&o)||o>86400)return 0;}
169
+ if(get(x,"launch_connection_id")||get(x,"environment")||get(x,"binding_version")){int64_t binding=0,h=0,o=0;const char*env=text(x,"environment"),*mode=text(policy,"offline_mode");if(!uuid(text(x,"launch_connection_id"))||!env||(strcmp(env,"live")&&strcmp(env,"sandbox"))||!num(x,"binding_version",&binding)||binding<1||!uuid(text(x,"session_id"))||session<=issued||expires>session||!num(policy,"heartbeat_seconds",&h)||h<600||!mode||!strcmp(mode,"permanent")||!num(policy,"offline_seconds",&o)||o>86400)return 0;}
170
170
  if(released>issued||(maintenance>0&&(!text(x,"app_version")||released==0||released>maintenance)))return 0;
171
171
  return 1;
172
172
  }
@@ -419,7 +419,7 @@ static int prepare_credential(ln_client*c){
419
419
  static int accept_credential(ln_client*c,const cJSON*result){
420
420
  if(logout_binding_blocked(c,result))return 0;
421
421
  if(cJSON_IsTrue(get(c->logout_state,"signed_out"))){cJSON_ReplaceItemInObjectCaseSensitive(c->logout_state,"signed_out",cJSON_CreateBool(0));if(!save_logout_state(c))return 0;}
422
- if(get(result,"logout_ticket")){if(!prepare_credential(c))return 0;cJSON_DeleteItemFromObjectCaseSensitive(c->auth,"logout_ticket");cJSON_AddItemToObject(c->auth,"logout_ticket",cJSON_Duplicate(get(result,"logout_ticket"),1));c->auth_dirty=1;if(!save_credential(c))return 0;}if(!temporary(c)||(text(c->auth,"device_key")&&text(c->auth,"device_key")[0]))return 1;
422
+ if(get(result,"logout_ticket")){if(!prepare_credential(c))return 0;cJSON_DeleteItemFromObjectCaseSensitive(c->auth,"logout_ticket");cJSON_AddItemToObject(c->auth,"logout_ticket",cJSON_Duplicate(get(result,"logout_ticket"),1));c->auth_dirty=1;if(!save_credential(c))return 0;}if(!temporary(c)||(text(c->auth,"device_key")&&text(c->auth,"device_key")[0]&&(!text(result,"device_key")||!text(result,"device_key")[0])))return 1;
423
423
  const char*k=text(result,"device_key");if(!credential_secret(k,"lv_dev_")){if(strncmp(text(c->cfg,"license_key"),"lv_tmp_",7)&&!(text(c->cfg,"identity_token")&&text(c->cfg,"identity_token")[0]))return 1;strcpy(c->error,"DEVICE_CREDENTIAL_MISSING");return 0;}if(!prepare_credential(c))return 0;cJSON_ReplaceItemInObjectCaseSensitive(c->auth,"device_key",cJSON_CreateString(k));c->auth_dirty=1;return save_credential(c);
424
424
  }
425
425
  struct buffer{char data[LIMIT+1];size_t size;int oversized;};
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: licentivo-launch
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.7
4
+ version: 0.1.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Licentivo Launch contributors
@@ -64,124 +64,6 @@ files:
64
64
  - vendor/c/vendor/monocypher-ed25519.h
65
65
  - vendor/c/vendor/monocypher.c
66
66
  - vendor/c/vendor/monocypher.h
67
- - vendor/curl/COPYING.txt
68
- - vendor/curl/bin/libcurl-x64.dll
69
- - vendor/curl/include/brotli/decode.h
70
- - vendor/curl/include/brotli/encode.h
71
- - vendor/curl/include/brotli/port.h
72
- - vendor/curl/include/brotli/shared_dictionary.h
73
- - vendor/curl/include/brotli/types.h
74
- - vendor/curl/include/curl/curl.h
75
- - vendor/curl/include/curl/curlver.h
76
- - vendor/curl/include/curl/easy.h
77
- - vendor/curl/include/curl/header.h
78
- - vendor/curl/include/curl/mprintf.h
79
- - vendor/curl/include/curl/multi.h
80
- - vendor/curl/include/curl/options.h
81
- - vendor/curl/include/curl/stdcheaders.h
82
- - vendor/curl/include/curl/system.h
83
- - vendor/curl/include/curl/typecheck-gcc.h
84
- - vendor/curl/include/curl/urlapi.h
85
- - vendor/curl/include/curl/websockets.h
86
- - vendor/curl/include/libpsl.h
87
- - vendor/curl/include/libssh2.h
88
- - vendor/curl/include/libssh2_publickey.h
89
- - vendor/curl/include/libssh2_sftp.h
90
- - vendor/curl/include/nghttp2/nghttp2.h
91
- - vendor/curl/include/nghttp2/nghttp2ver.h
92
- - vendor/curl/include/nghttp3/nghttp3.h
93
- - vendor/curl/include/nghttp3/version.h
94
- - vendor/curl/include/ngtcp2/ngtcp2.h
95
- - vendor/curl/include/ngtcp2/ngtcp2_crypto.h
96
- - vendor/curl/include/ngtcp2/ngtcp2_crypto_quictls.h
97
- - vendor/curl/include/ngtcp2/version.h
98
- - vendor/curl/include/openssl/aes.h
99
- - vendor/curl/include/openssl/asn1.h
100
- - vendor/curl/include/openssl/asn1t.h
101
- - vendor/curl/include/openssl/bio.h
102
- - vendor/curl/include/openssl/blowfish.h
103
- - vendor/curl/include/openssl/bn.h
104
- - vendor/curl/include/openssl/buffer.h
105
- - vendor/curl/include/openssl/camellia.h
106
- - vendor/curl/include/openssl/cast.h
107
- - vendor/curl/include/openssl/chacha.h
108
- - vendor/curl/include/openssl/cmac.h
109
- - vendor/curl/include/openssl/cms.h
110
- - vendor/curl/include/openssl/comp.h
111
- - vendor/curl/include/openssl/conf.h
112
- - vendor/curl/include/openssl/crypto.h
113
- - vendor/curl/include/openssl/ct.h
114
- - vendor/curl/include/openssl/curve25519.h
115
- - vendor/curl/include/openssl/des.h
116
- - vendor/curl/include/openssl/dh.h
117
- - vendor/curl/include/openssl/dsa.h
118
- - vendor/curl/include/openssl/dtls1.h
119
- - vendor/curl/include/openssl/ec.h
120
- - vendor/curl/include/openssl/ecdh.h
121
- - vendor/curl/include/openssl/ecdsa.h
122
- - vendor/curl/include/openssl/engine.h
123
- - vendor/curl/include/openssl/err.h
124
- - vendor/curl/include/openssl/evp.h
125
- - vendor/curl/include/openssl/hkdf.h
126
- - vendor/curl/include/openssl/hmac.h
127
- - vendor/curl/include/openssl/idea.h
128
- - vendor/curl/include/openssl/kdf.h
129
- - vendor/curl/include/openssl/lhash.h
130
- - vendor/curl/include/openssl/md4.h
131
- - vendor/curl/include/openssl/md5.h
132
- - vendor/curl/include/openssl/mlkem.h
133
- - vendor/curl/include/openssl/modes.h
134
- - vendor/curl/include/openssl/obj_mac.h
135
- - vendor/curl/include/openssl/objects.h
136
- - vendor/curl/include/openssl/ocsp.h
137
- - vendor/curl/include/openssl/opensslconf.h
138
- - vendor/curl/include/openssl/opensslfeatures.h
139
- - vendor/curl/include/openssl/opensslv.h
140
- - vendor/curl/include/openssl/ossl_typ.h
141
- - vendor/curl/include/openssl/pem.h
142
- - vendor/curl/include/openssl/pkcs12.h
143
- - vendor/curl/include/openssl/pkcs7.h
144
- - vendor/curl/include/openssl/poly1305.h
145
- - vendor/curl/include/openssl/posix_time.h
146
- - vendor/curl/include/openssl/rand.h
147
- - vendor/curl/include/openssl/rc2.h
148
- - vendor/curl/include/openssl/rc4.h
149
- - vendor/curl/include/openssl/ripemd.h
150
- - vendor/curl/include/openssl/rsa.h
151
- - vendor/curl/include/openssl/safestack.h
152
- - vendor/curl/include/openssl/sha.h
153
- - vendor/curl/include/openssl/sm3.h
154
- - vendor/curl/include/openssl/sm4.h
155
- - vendor/curl/include/openssl/srtp.h
156
- - vendor/curl/include/openssl/ssl.h
157
- - vendor/curl/include/openssl/ssl3.h
158
- - vendor/curl/include/openssl/stack.h
159
- - vendor/curl/include/openssl/tls1.h
160
- - vendor/curl/include/openssl/ts.h
161
- - vendor/curl/include/openssl/txt_db.h
162
- - vendor/curl/include/openssl/ui.h
163
- - vendor/curl/include/openssl/x509.h
164
- - vendor/curl/include/openssl/x509_vfy.h
165
- - vendor/curl/include/openssl/x509v3.h
166
- - vendor/curl/include/zconf.h
167
- - vendor/curl/include/zdict.h
168
- - vendor/curl/include/zlib.h
169
- - vendor/curl/include/zlib_name_mangling.h
170
- - vendor/curl/include/zstd.h
171
- - vendor/curl/include/zstd_errors.h
172
- - vendor/curl/lib/libcurl.dll.a
173
- - vendor/curl/licenses/brotli/LICENSE.txt
174
- - vendor/curl/licenses/certdata/LICENSE.url
175
- - vendor/curl/licenses/libpsl/COPYING.txt
176
- - vendor/curl/licenses/libressl/COPYING.txt
177
- - vendor/curl/licenses/libssh2/COPYING.txt
178
- - vendor/curl/licenses/nghttp2/COPYING.txt
179
- - vendor/curl/licenses/nghttp3/COPYING.txt
180
- - vendor/curl/licenses/ngtcp2/COPYING.txt
181
- - vendor/curl/licenses/psl/LICENSE.txt
182
- - vendor/curl/licenses/trurl/COPYING.txt
183
- - vendor/curl/licenses/zlibng/LICENSE.md
184
- - vendor/curl/licenses/zstd/LICENSE.txt
185
67
  homepage: https://www.licentivo.com/en/launch.html
186
68
  licenses:
187
69
  - MIT
@@ -1,22 +0,0 @@
1
- COPYRIGHT AND PERMISSION NOTICE
2
-
3
- Copyright (c) 1996 - 2026, Daniel Stenberg, <daniel@haxx.se>, and many
4
- contributors, see the THANKS file.
5
-
6
- All rights reserved.
7
-
8
- Permission to use, copy, modify, and distribute this software for any purpose
9
- with or without fee is hereby granted, provided that the above copyright
10
- notice and this permission notice appear in all copies.
11
-
12
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN
15
- NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
16
- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
17
- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
18
- OR OTHER DEALINGS IN THE SOFTWARE.
19
-
20
- Except as contained in this notice, the name of a copyright holder shall not
21
- be used in advertising or otherwise to promote the sale, use or other dealings
22
- in this Software without prior written authorization of the copyright holder.
Binary file