if (!strcmp(buf + 7, "Keepalive")) {
vpninfo->ssl_times.keepalive = atol(colon);
+ } else if (!strcmp(buf + 7, "Lease-Duration") ||
+ !strcmp(buf + 7, "Session-Timeout") ||
+ !strcmp(buf + 7, "Session-Timeout-Remaining")) {
+
+ /* XX: Distinction between Lease-Duration and Session-Timeout is rather unclear. Cisco doc:
+ * https://www.cisco.com/assets/sol/sb/RV345P_Emulators/RV345P_Emulator_v1-0-01-17/help/help/t_SSL_VPN.html
+ * Empirically, it appears that the best behavior is to accept whichever of these headers has the
+ * lowest non-zero value.
+ */
+ long j = atol(colon);
+ if (j && (!vpninfo->auth_expiration || j < vpninfo->auth_expiration))
+ vpninfo->auth_expiration = time(NULL) + j;
} else if (!strcmp(buf + 7, "Idle-Timeout")) {
vpninfo->idle_timeout = atol(colon);
} else if (!strcmp(buf + 7, "DPD")) {
} else if (!xmlnode_get_val(xml_node, "mtu", &s))
vpninfo->ip_info.mtu = atoi(s);
else if (!xmlnode_get_val(xml_node, "lifetime", &s))
- vpn_progress(vpninfo, PRG_INFO, _("Session will expire after %d minutes.\n"), atoi(s)/60);
+ vpninfo->auth_expiration = time(NULL) + atol(s);
else if (!xmlnode_get_val(xml_node, "disconnect-on-idle", &s)) {
int sec = atoi(s);
vpn_progress(vpninfo, PRG_INFO, _("Idle timeout is %d minutes.\n"), sec/60);
import java.io.*;
import java.util.*;
+import java.time.Instant;
import org.infradead.libopenconnect.LibOpenConnect;
public final class LibTest {
int idleTimeout = lib.getIdleTimeout();
System.out.println("Idle Timeout: " + idleTimeout + " seconds");
+ Instant authExpiration = lib.getAuthExpiration();
+ System.out.println("Auth Expiration: " + authExpiration.toString());
printIPInfo(lib.getIPInfo());
if (lib.setupDTLS(60) != 0)
import java.util.ArrayList;
import java.util.HashMap;
+import java.time.Instant;
public abstract class LibOpenConnect {
public synchronized native String getDTLSCompression();
public synchronized native String getProtocol();
public synchronized native int getIdleTimeout();
+ public synchronized native Instant getAuthExpiration();
/* certificate info */
return openconnect_get_idle_timeout(ctx->vpninfo);
}
+JNIEXPORT jobject JNICALL Java_org_infradead_libopenconnect_LibOpenConnect_getAuthExpiration(
+ JNIEnv *jenv, jobject jobj)
+{
+ struct libctx *ctx = getctx(jenv, jobj);
+ jmethodID mid;
+ jobject result;
+ jclass jcls;
+ time_t auth_expiration;
+
+ if (!ctx)
+ return NULL;
+
+ auth_expiration = openconnect_get_auth_expiration(ctx->vpninfo);
+ jcls = (*ctx->jenv)->FindClass(ctx->jenv, "java/time/Instant");
+ if (jcls == NULL)
+ goto err;
+ mid = (*jenv)->GetStaticMethodID(jenv, jcls, "ofEpochSecond", "(J)Ljava/time/Instant;");
+ if (!mid)
+ goto err;
+ result = (*jenv)->CallStaticObjectMethod(jenv, jcls, mid, auth_expiration);
+ if (result == NULL)
+ goto err;
+
+ return result;
+
+err:
+ return NULL;
+}
+
+
/* simple cases: return a const string (no need to free it) */
#define RETURN_STRING_START \
global:
openconnect_set_cookie;
openconnect_set_allow_insecure_crypto;
+ openconnect_get_auth_expiration;
} OPENCONNECT_5_6;
OPENCONNECT_PRIVATE {
return vpninfo->idle_timeout;
}
+time_t openconnect_get_auth_expiration(struct openconnect_info *vpninfo)
+{
+ return vpninfo->auth_expiration;
+}
+
int openconnect_get_ip_info(struct openconnect_info *vpninfo,
const struct oc_ip_info **info,
const struct oc_vpn_option **cstp_options,
ssl_compr ? " + " : "", ssl_compr ? : "",
vpninfo->proto->udp_protocol ? : "UDP", udp_compr ? " + " : "", udp_compr ? : "",
dtls_state);
+ if (vpninfo->auth_expiration != 0)
+ vpn_progress(vpninfo, PRG_INFO, _("Session authentication will expire at %s"),
+ ctime(&vpninfo->auth_expiration));
}
#ifndef _WIN32
int reconnect_timeout;
int reconnect_interval;
int dtls_attempt_period;
+ time_t auth_expiration;
time_t new_dtls_started;
#if defined(OPENCONNECT_OPENSSL)
SSL_CTX *dtls_ctx;
* API version 5.7:
* - Add openconnect_set_cookie()
* - Add openconnect_set_allow_insecure_crypto()
+ * - Add openconnect_get_auth_expiration()
*
* API version 5.6 (v8.06; 2020-03-31):
* - Add openconnect_set_trojan_interval()
void openconnect_set_dpd(struct openconnect_info *, int min_seconds);
void openconnect_set_trojan_interval(struct openconnect_info *, int seconds);
int openconnect_get_idle_timeout(struct openconnect_info *);
+time_t openconnect_get_auth_expiration(struct openconnect_info *);
/* The returned structures are owned by the library and may be freed/replaced
due to rekey or reconnect. Assume that once the mainloop starts, the