# Extended Configuration

LicenseSpring offers many features to tailor the setup to meet user needs through the `Configuration` and `ExtendedOptions` classes. Throughout this tutorial, we'll provide a comprehensive overview of these classes and how they are used to manage settings.

In addition to the theoretical understanding, this tutorial also offers practical guidance. You'll find instructions on how to set up a proxy, a crucial element in various software setups. We'll also cover the important topic of SSL checks, discussing their importance and how to integrate them effectively.

This tutorial will provide readers with a solid understanding of the `Configuration` and `ExtendedOptions` classes, acquired practical skills in configuring proxies, and obtained insights into enhancing security through SSL checks.

**Swift** SDK does not have separated `ExtendedConfiguration`: all properties are defined in the `Configuration` itself.

### Accessing Current Configuration

The current configuration can be retrieved by calling `currentConfig()` on a `LicenseManager` instance in the C++ SDK:

{% tabs %}
{% tab title="C++" %}

```cpp
configuration = licenseManager->currentConfig();
```

{% endtab %}

{% tab title="Python" %}

```python
manager = LicenseManager(conf)

config = manager.current_config()

print(config)
```

{% endtab %}

{% tab title="Java" %}

```java
LicenseSpringConfiguration config = licenseManager.getConfig();
```

{% endtab %}
{% endtabs %}

It is also possible to reconfigure the current configuration, rather than having to create a new `Configuration` object with:

{% tabs %}
{% tab title="C++" %}

```cpp
reconfigure(configuration);
```

{% endtab %}

{% tab title="Python" %}

```python
manager = LicenseManager(conf)

manager.reconfigure(
        Configuration(
            product="lkprod2",
            api_key="new_key",
            shared_key="new_key",
            file_key="file_key",
            file_iv="file_iv",
            file_path="bb",
            grace_period_conf=12,
            is_guard_file_enabled=True,
        )
    )
```

{% endtab %}

{% tab title="Java" %}

```java
licenseManager.reinitialize(configuration);
```

{% endtab %}

{% tab title="Swift" %}

```swift
try licenseManager.reconfigure(
            appName: "AA[[",
            appVersion: "2.0.1",
            airgapKey: "someAirgapKey",
            skipResponseSignatureChecks: true)
```

{% endtab %}
{% endtabs %}

{% hint style="danger" %}
**Warning:** `reconfigure()` is not thread safe.
{% endhint %}

### Network Information and Timeout

To activate the gathering of network information, you need to declare it during the configuration phase of the implementation, as follows:

{% tabs %}
{% tab title="C++" %}

```cpp
extendedOptions.collectNetworkInfo(true);
```

{% endtab %}

{% tab title="C#" %}

```csharp
extendedOptions.CollectNetworkInfo = true;
//OR
configuration.CollectNetworkInfo = true;
```

{% endtab %}

{% tab title="Swift" %}

```swift
configuration.collectHostNameAndLocalIP = true
```

{% endtab %}

{% tab title="Java" %}

```java
configuration.storeMachineInfo = true;
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Note: Network data collection is deactivated by default when left unset.
{% endhint %}

Whether network collection is enabled can be checked after configuration with:

{% tabs %}
{% tab title="C++" %}

```cpp
bool enabled = extendedOptions.isCollectNetworkInfoEnabled();
//OR
bool enabled = configuration->isCollectNetworkInfoEnabled();
```

{% endtab %}

{% tab title="C#" %}

```csharp
bool enabled = extendedOptions.CollectNetworkInfo;
//OR
bool enabled = configuration.CollectNetworkInfo;
```

{% endtab %}

{% tab title="Swift" %}

```swift
configuration.collectHostNameAndLocalIP
```

{% endtab %}

{% tab title="Java" %}

```java
boolean enabled = baseConfiguration.isStoreMachineInfo();
```

{% endtab %}
{% endtabs %}

A variety of network-related information can be accessed through both `ExtendedOptions` and `Configuration` in C++ and `Configuration` in .NET.

In C++, a `NetworkInfo` object is returned when `getNetworkInfo` is called. The `NetworkInfo` object consists of the following:

* IP address
* MAC address
* Host name

In .NET, the IP address, MAC address, and host name are stored separately in `Configuration`.

In the Python SDK, network information is managed within the [**Python Hardware (Device) IDs**](broken://pages/19ffde87b0f9d3bf1cf5dff241ef483bffd27085) class, which is designed to be customizable. If a user prefers not to send network information, they can override the relevant method in the class to return `None`. This information can be accessed using the following:

{% tabs %}
{% tab title="C++" %}

```cpp
//Through ExtendedOptions
const NetworkInfo& networkInfo = extendedOptions.getNetworkInfo();
//Through Configuration
const NetworkInfo& networkInfo = configuration->getNetworkInfo();

string IPAddress = networkInfo.ip();
string MACAddress = networkInfo.mac();
string hostname = networkInfo.hostName();
```

{% endtab %}

{% tab title="C#" %}

```csharp
string hostname = configuration.Hostname;
string ip = configuration.LocalIp;
string MACAddress = configuration.MACAddress;
```

{% endtab %}

{% tab title="Python" %}

```python
# This will overwrite HardwareIdProvided and disable sending network data and OS data.
# This approach allows you to disable fields which fit user needs or set them to some default value.

class CustomHardwareIdProvider(HardwareIdProvider):

    def get_os_ver(self):
        return None

    def get_hostname(self):
        return None

    def get_ip(self):
        return None

    def get_is_vm(self):
        return False

    def get_vm_info(self):
        return None

    def get_mac_address(self):
        return None
```

{% endtab %}

{% tab title="Java" %}

```java
MachineInfo machineInfo = HardwareInfo.getMachineInfo();
String macAddress = machineInfo.getMacAddress();
String ipAddresses = machineInfo.getIpAddresses();
String hostname = machineInfo.getHostname();
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Note: The above code snippet assumes that a `Configuration` object named "configuration" and `ExtendedOptions` object named "extendedOptions" already exist.
{% endhint %}

#### Override Network Information

C++ offers a method for overriding network information, setting the `NetworkInfo` object stored within `ExtendedOptions`:

```cpp
extendedOptions.overrideNetworkInfo(networkInfo);
```

#### Network Timeout

Similarly, the network timeout of the configuration is stored in the same locations, and can be accessed with:

{% tabs %}
{% tab title="C++" %}

```cpp
long timeout = extendedOptions.getNetworkTimeout();
//OR
long timeout = configuration->getNetworkTimeout();
```

{% endtab %}

{% tab title="C#" %}

```csharp
int timeout = extendedOptions.NetworkTimeout;
//OR
int timeout = configuration.NetworkTimeout;
```

{% endtab %}

{% tab title="Swift" %}

```swift
configuration.networkTimeout
```

{% endtab %}

{% tab title="Java" %}

```java
// Request timeout in seconds, default is 10s
Long requestTimeout = configuration.getRequestTimeout(); 
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Note: In C++, the network timeout is represented as a long, while in .NET, it is represented as an int.
{% endhint %}

Configuring the network timeout is equally straightforward, accomplished in a comparable manner:

{% tabs %}
{% tab title="C++" %}

```cpp
extendedOptions.setNetworkTimeout(timeout);
//OR
configuration->setNetworkTimeout(timeout);
```

{% endtab %}

{% tab title="C#" %}

```csharp
extendedOptions.NetworkTimeout = timeout;
//OR
configuration.NetworkTimeout = timeout;
```

{% endtab %}

{% tab title="Swift" %}

```swift
configuration.networkTimeout = timeout // TimeInterval.
```

{% endtab %}

{% tab title="Java" %}

```java
LicenseSpringConfiguration config = LicenseSpringConfiguration
    .requestTimeout(15) // setting timeout to 15s
    .builder()
```

{% endtab %}
{% endtabs %}

The C++ SDK also allows to set and get the connection timeout, i.e. the value used for CURLOPT\_CONNECTTIMEOUT. It defaults to 7 seconds.

```cpp
extendedOptions.setConnectTimeout(timeout);
//OR
configuration->setConnectTimeout(timeout);
```

### Proxy Settings

Proxy settings are configuration parameters that allow you to route network traffic through an intermediary server, known as a proxy server. Proxy settings are another feature stored within `ExtendedOptions` and `Configuration` that can be accessed with:

{% tabs %}
{% tab title="C++" %}

```cpp
ProxySettings proxy = extendedOptions.getProxySettings();
//OR
ProxySettings proxy = configuration->getProxySettings();
```

{% endtab %}

{% tab title="C#" %}

```csharp
ProxySettings proxy = extendedOptions.Proxy;
//OR
ProxySettings proxy = configuration.Proxy;
```

{% endtab %}

{% tab title="Java" %}

```java
String proxyHost = config.getProxyHost();
Integer proxyPort = config.getProxyHost();
String proxyUser = config.getProxyHost();
String proxyPass = config.getProxyHost();
String proxyCertPath = config.getProxyCertPath();
```

{% endtab %}
{% endtabs %}

Proxy settings can be set as follows:

{% tabs %}
{% tab title="C++" %}

```cpp
extendedOptions.setProxySettings(proxySettings);
```

{% endtab %}

{% tab title="C#" %}

```csharp
extendedOptions.Proxy = proxySettings;
//OR
configuration.Proxy = proxySettings;
```

{% endtab %}

{% tab title="Swift" %}

```swift
configuration.proxyHost = "..."
configuration.proxyPort = 65535 // UInt16.
```

{% endtab %}

{% tab title="Java" %}

```java
LicenseSpringConfiguration config = LicenseSpringConfiguration
    .proxyHost("192.168.1.3")
    .proxyPort(3128)
    .proxyUser("test")
    .proxyPass("test")
    .builder()
```

{% endtab %}
{% endtabs %}

{% hint style="danger" %}
Exception: AuthorizationException thrown if authorization fails. To resolve, check and ensure proxy settings are correct.
{% endhint %}

In the Windows version of the C++ SDK, proxy settings can be automatically fetched through the WinHTTP API.

If the proxy is autoconfigured through a `.pac` file over the network, the SDK reads which proxy is used to reach `api.licensespring.com` or some other custom API URL.

Proxy credentials are read from Windows Credential Manager, and the caller needs to supply the exact Windows Credential target that holds the credentials:

```cpp
LicenseSpring::ProxySettings proxy;
std::string serviceUrl = "https://api.licensespring.com";
std::string credentialTarget = "WindowsProxyCredential"; //depends on the proxy setu
bool throwExceptions = true; // false by default
proxy.fetchProxySettings(serviceUrl, credentialTarget, throwExceptions);
```

### Native Transport Layer Security

The C++ SDK offers the opportunity to enable or disable native TLS for curl.

{% hint style="info" %}
The SDK uses Schannel as a native TLS provider for Windows, and non-native OpenSSL on other platforms. Before modifying the default settings of the SDK, it's crucial to have a clear understanding of the implications.

Make sure to consult the curl documentation for guidance:

[**SSL/TLS Documentation**](https://curl.se/docs/sslcerts.html)

[**SSL/TLS Library Comparison**](https://curl.se/docs/ssl-compared.html)
{% endhint %}

Enable native TLS on Windows by running:

{% tabs %}
{% tab title="C++" %}

```cpp
extendedOptions.setUseNativeTLS(true);
```

{% endtab %}

{% tab title="Java" %}

```java
LicenseSpringConfiguration config = LicenseSpringConfiguration
    .sslConfig(sslConfig)
    .builder()
```

{% endtab %}
{% endtabs %}

To later check for whether native TLS is being used:

```cpp
bool enabled = extendedOptions.isNativeTLSEnabled();
```

### Secure Sockets Layer Certificate Verification

Similar to native TLS, the C++ SDK allows developers to decide whether SSL certificate verification is to be enabled or disabled.

{% hint style="info" %}
Note: By default, SSL certificate verification is **enabled**.

We strongly discourage disabling this option.

For more information, see the [**SSL Certificate Verification Documentation**](https://curl.se/libcurl/c/CURLOPT_SSL_VERIFYPEER.html).
{% endhint %}

To disable SSL certificate verification:

```cpp
extendedOptions.enableSSLCheck(false);
```

There is also a checker for whether SSL certificate verification is enabled:

```cpp
bool enabled = extendedOptions.isSSLCheckEnabled();
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.licensespring.com/sdks/tutorials/advanced-usage/extended-configuration.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
