lemonldap-ng/doc/pages/documentation/current/cli_examples.html
2019-12-21 16:54:57 +01:00

535 lines
21 KiB
HTML

<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8" />
<title>documentation:2.0:cli_examples</title>
<meta name="generator" content="DokuWiki"/>
<meta name="robots" content="index,follow"/>
<meta name="keywords" content="documentation,2.0,cli_examples"/>
<link rel="search" type="application/opensearchdescription+xml" href="lib/exe/opensearch.html" title="LemonLDAP::NG"/>
<link rel="start" href="cli_examples.html"/>
<link rel="contents" href="cli_examples.html" title="Sitemap"/>
<link rel="stylesheet" type="text/css" href="lib/exe/css.php.t.bootstrap3.css"/>
<!-- //if:usedebianlibs
<link rel="stylesheet" type="text/css" href="/javascript/bootstrap/css/bootstrap.min.css" />
//elsif:useexternallibs
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"></script>
//elsif:cssminified
<link rel="stylesheet" type="text/css" href="/static/bwr/bootstrap/dist/css/bootstrap.min.css" />
//else -->
<link rel="stylesheet" type="text/css" href="/static/bwr/bootstrap/dist/css/bootstrap.css" />
<!-- //endif -->
<script type="text/javascript">/*<![CDATA[*/var NS='documentation:2.0';var JSINFO = {"id":"documentation:2.0:cli_examples","namespace":"documentation:2.0"};
/*!]]>*/</script>
<script type="text/javascript" charset="utf-8" src="lib/exe/js.php.t.bootstrap3.js"></script>
<!-- //if:usedebianlibs
<script type="text/javascript" src="/javascript/jquery/jquery.min.js"></script>
//elsif:useexternallibs
<script type="text/javascript" src="http://code.jquery.com/jquery-2.2.0.min.js"></script>
//elsif:jsminified
<script type="text/javascript" src="/static/bwr/jquery/dist/jquery.min.js"></script>
//else -->
<script type="text/javascript" src="/static/bwr/jquery/dist/jquery.js"></script>
<!-- //endif -->
<!-- //if:usedebianlibs
<script type="text/javascript" src="/javascript/jquery-ui/jquery-ui.min.js"></script>
//elsif:useexternallibs
<script type="text/javascript" src="http://code.jquery.com/ui/1.10.4/jquery-ui.min.js"></script>
//elsif:jsminified
<script type="text/javascript" src="/static/bwr/jquery-ui/jquery-ui.min.js"></script>
//else -->
<script type="text/javascript" src="/static/bwr/jquery-ui/jquery-ui.js"></script>
<!-- //endif -->
</head>
<body>
<div class="dokuwiki export container">
<!-- TOC START -->
<div id="dw__toc">
<h3 class="toggle">Table of Contents</h3>
<div>
<ul class="toc">
<li class="level1"><div class="li"><a href="#saverestore_configuration">Save/restore configuration</a></div></li>
<li class="level1"><div class="li"><a href="#configure_https">Configure HTTPS</a></div></li>
<li class="level1"><div class="li"><a href="#configure_sessions_backend">Configure sessions backend</a></div></li>
<li class="level1"><div class="li"><a href="#configure_virtual_host">Configure virtual host</a></div></li>
<li class="level1"><div class="li"><a href="#configure_ldap_authentication_backend">Configure LDAP authentication backend</a></div></li>
<li class="level1"><div class="li"><a href="#configure_saml_identity_provider">Configure SAML Identity Provider</a></div></li>
<li class="level1"><div class="li"><a href="#register_an_saml_service_provider">Register an SAML Service Provider</a></div></li>
<li class="level1"><div class="li"><a href="#configure_openid_connect_identity_provider">Configure OpenID Connect Identity Provider</a></div></li>
<li class="level1"><div class="li"><a href="#register_an_openid_connect_relying_party">Register an OpenID Connect Relying Party</a></div></li>
<li class="level1"><div class="li"><a href="#categories_and_applications_in_menu">Categories and applications in menu</a></div></li>
<li class="level1"><div class="li"><a href="#encryption_key">Encryption key</a></div></li>
</ul>
</div>
</div>
<!-- TOC END -->
<h1 class="sectionedit1" id="command_line_interface_lemonldap-ng-cli_examples">Command Line Interface (lemonldap-ng-cli) examples</h1>
<div class="level1">
<p>
This page shows some examples of <abbr title="LemonLDAP::NG">LL::NG</abbr> Command Line Interface. See <a href="configlocation.html#command_line_interface_cli" class="wikilink1" title="documentation:2.0:configlocation">how to use the command</a>.
</p>
</div>
<!-- EDIT1 SECTION "Command Line Interface (lemonldap-ng-cli) examples" [1-205] -->
<h2 class="sectionedit2" id="saverestore_configuration">Save/restore configuration</h2>
<div class="level2">
<p>
This part requires LLNG 2.0.5 at least.
</p>
<p>
Save:
</p>
<pre class="code sh">/usr/share/lemonldap-ng/bin/lemonldap-ng-cli save &gt;config.json</pre>
<p>
Restore:
</p>
<pre class="code shell">/usr/share/lemonldap-ng/bin/lemonldap-ng-cli restore config.json
# Or
/usr/share/lemonldap-ng/bin/lemonldap-ng-cli restore - &lt;config.json</pre>
</div>
<!-- EDIT2 SECTION "Save/restore configuration" [206-543] -->
<h2 class="sectionedit3" id="configure_https">Configure HTTPS</h2>
<div class="level2">
<p>
When setting HTTPS, you first need to modify Apache/Nginx configuration, then you must configure <abbr title="LemonLDAP::NG">LL::NG</abbr> to change portal <abbr title="Uniform Resource Locator">URL</abbr>, Handler redirections, cookie settings, ...
</p>
<pre class="code">/usr/share/lemonldap-ng/bin/lemonldap-ng-cli -yes 1 \
set \
portal https://auth.example.com \
mailUrl https://auth.example.com/resetpwd \
registerUrl https://auth.example.com/register \
https 1 \
securedCookie 1</pre>
</div>
<!-- EDIT3 SECTION "Configure HTTPS" [544-1014] -->
<h2 class="sectionedit4" id="configure_sessions_backend">Configure sessions backend</h2>
<div class="level2">
<p>
For production, it is recommended to use <a href="browseablesessionbackend.html" class="wikilink1" title="documentation:2.0:browseablesessionbackend">Browseable session backend</a>. Once tables are created with columns corresponding to index, the following commands can be executed to set all the session backends.
</p>
<p>
In this example we have:
</p>
<ul>
<li class="level1"><div class="li"> Backend: PostGreSQL</div>
</li>
<li class="level1"><div class="li"> DB user: lemonldaplogin</div>
</li>
<li class="level1"><div class="li"> DB password: lemonldappw</div>
</li>
<li class="level1"><div class="li"> Database: lemonldapdb</div>
</li>
<li class="level1"><div class="li"> Host: pg.example.com</div>
</li>
</ul>
<ul>
<li class="level1"><div class="li"> <abbr title="Single Sign On">SSO</abbr> sessions:</div>
</li>
</ul>
<pre class="code">/usr/share/lemonldap-ng/bin/lemonldap-ng-cli -yes 1 \
delKey \
globalStorageOptions Directory \
globalStorageOptions LockDirectory
/usr/share/lemonldap-ng/bin/lemonldap-ng-cli -yes 1 \
set \
globalStorage Apache::Session::Browseable::Postgres
/usr/share/lemonldap-ng/bin/lemonldap-ng-cli -yes 1 \
addKey \
globalStorageOptions DataSource &#039;DBI:Pg:database=lemonldapdb;host=pg.example.com&#039; \
globalStorageOptions UserName &#039;lemonldaplogin&#039; \
globalStorageOptions Password &#039;lemonldappw&#039; \
globalStorageOptions Commit 1 \
globalStorageOptions Index &#039;ipAddr _whatToTrace user&#039; \
globalStorageOptions TableName &#039;sessions&#039;
</pre>
<ul>
<li class="level1"><div class="li"> Persistent sessions:</div>
</li>
</ul>
<pre class="code">/usr/share/lemonldap-ng/bin/lemonldap-ng-cli -yes 1 \
delKey \
persistentStorageOptions Directory \
persistentStorageOptions LockDirectory
/usr/share/lemonldap-ng/bin/lemonldap-ng-cli -yes 1 \
set \
persistentStorage Apache::Session::Browseable::Postgres
/usr/share/lemonldap-ng/bin/lemonldap-ng-cli -yes 1 \
addKey \
persistentStorageOptions DataSource &#039;DBI:Pg:database=lemonldapdb;host=pg.example.com&#039; \
persistentStorageOptions UserName &#039;lemonldaplogin&#039; \
persistentStorageOptions Password &#039;lemonldappw&#039; \
persistentStorageOptions Commit 1 \
persistentStorageOptions Index &#039;_session_uid&#039; \
persistentStorageOptions TableName &#039;psessions&#039;</pre>
<ul>
<li class="level1"><div class="li"> <abbr title="Central Authentication Service">CAS</abbr> sessions</div>
</li>
</ul>
<pre class="code">/usr/share/lemonldap-ng/bin/lemonldap-ng-cli -yes 1 \
set \
casStorage Apache::Session::Browseable::Postgres
/usr/share/lemonldap-ng/bin/lemonldap-ng-cli -yes 1 \
addKey \
casStorageOptions DataSource &#039;DBI:Pg:database=lemonldapdb;host=pg.example.com&#039; \
casStorageOptions UserName &#039;lemonldaplogin&#039; \
casStorageOptions Password &#039;lemonldappw&#039; \
casStorageOptions Commit 1 \
casStorageOptions Index &#039;_cas_id&#039; \
casStorageOptions TableName &#039;cassessions&#039;</pre>
<ul>
<li class="level1"><div class="li"> <abbr title="Security Assertion Markup Language">SAML</abbr> sessions</div>
</li>
</ul>
<pre class="code">/usr/share/lemonldap-ng/bin/lemonldap-ng-cli -yes 1 \
set \
samlStorage Apache::Session::Browseable::Postgres
/usr/share/lemonldap-ng/bin/lemonldap-ng-cli -yes 1 \
addKey \
samlStorageOptions DataSource &#039;DBI:Pg:database=lemonldapdb;host=pg.example.com&#039; \
samlStorageOptions UserName &#039;lemonldaplogin&#039; \
samlStorageOptions Password &#039;lemonldappw&#039; \
samlStorageOptions Commit 1 \
samlStorageOptions Index &#039;_saml_id ProxyID _nameID _assert_id _art_id _session_id&#039; \
samlStorageOptions TableName &#039;samlsessions&#039;</pre>
<ul>
<li class="level1"><div class="li"> OpenID Connect sessions</div>
</li>
</ul>
<pre class="code">/usr/share/lemonldap-ng/bin/lemonldap-ng-cli -yes 1 \
set \
oidcStorage Apache::Session::Browseable::Postgres
/usr/share/lemonldap-ng/bin/lemonldap-ng-cli -yes 1 \
addKey \
oidcStorageOptions DataSource &#039;DBI:Pg:database=lemonldapdb;host=pg.example.com&#039; \
oidcStorageOptions UserName &#039;lemonldaplogin&#039; \
oidcStorageOptions Password &#039;lemonldappw&#039; \
oidcStorageOptions Commit 1 \
oidcStorageOptions TableName &#039;oidcsessions&#039;</pre>
</div>
<!-- EDIT4 SECTION "Configure sessions backend" [1015-4603] -->
<h2 class="sectionedit5" id="configure_virtual_host">Configure virtual host</h2>
<div class="level2">
<p>
A virtual host must be defined in Apache/Nginx and access rules and exported headers must be configured in <abbr title="LemonLDAP::NG">LL::NG</abbr>.
</p>
<p>
In this example we have:
</p>
<ul>
<li class="level1"><div class="li"> host: test.example.com</div>
</li>
<li class="level1"><div class="li"> Access rules:</div>
<ul>
<li class="level2"><div class="li"> default =&gt; accept</div>
</li>
<li class="level2"><div class="li"> Logout: ^/logout\.php =&gt; logout_sso</div>
</li>
</ul>
</li>
<li class="level1"><div class="li"> Headers:</div>
<ul>
<li class="level2"><div class="li"> Auth-User: $uid</div>
</li>
<li class="level2"><div class="li"> Auth-Mail: $mail</div>
</li>
</ul>
</li>
</ul>
<pre class="code">/usr/share/lemonldap-ng/bin/lemonldap-ng-cli -yes 1 \
addKey \
&#039;locationRules/test.example.com&#039; &#039;default&#039; &#039;accept&#039; \
&#039;locationRules/test.example.com&#039; &#039;(?#Logout)^/logout\.php&#039; &#039;logout_sso&#039; \
&#039;exportedHeaders/test.example.com&#039; &#039;Auth-User&#039; &#039;$uid&#039; \
&#039;exportedHeaders/test.example.com&#039; &#039;Auth-Mail&#039; &#039;$mail&#039;</pre>
</div>
<!-- EDIT5 SECTION "Configure virtual host" [4604-5304] -->
<h2 class="sectionedit6" id="configure_ldap_authentication_backend">Configure LDAP authentication backend</h2>
<div class="level2">
<p>
In this example we use:
</p>
<ul>
<li class="level1"><div class="li"> LDAP server: <a href="cli_examples.html" class="urlextern" title="ldap://ldap.example.com" rel="nofollow">ldap://ldap.example.com</a></div>
</li>
<li class="level1"><div class="li"> LDAP Bind <abbr title="Distinguished Name">DN</abbr> : cn=lemonldapng,ou=dsa,dc=example,dc=com</div>
</li>
<li class="level1"><div class="li"> LDAP Bind PW: changeit</div>
</li>
<li class="level1"><div class="li"> LDAP search base: ou=users,dc=example,dc=com</div>
</li>
<li class="level1"><div class="li"> LDAP attributes:</div>
<ul>
<li class="level2"><div class="li"> uid =&gt; uid</div>
</li>
<li class="level2"><div class="li"> cn =&gt; cn</div>
</li>
<li class="level2"><div class="li"> mail =&gt; mail</div>
</li>
<li class="level2"><div class="li"> sn =&gt; sn</div>
</li>
<li class="level2"><div class="li"> givenName =&gt; givenName</div>
</li>
<li class="level2"><div class="li"> mobile =&gt; mobile</div>
</li>
</ul>
</li>
<li class="level1"><div class="li"> LDAP group base: ou=groups,dc=example,dc=com</div>
</li>
<li class="level1"><div class="li"> Use recursive search for groups</div>
</li>
</ul>
<pre class="code">/usr/share/lemonldap-ng/bin/lemonldap-ng-cli -yes 1 \
set \
authentication LDAP \
userDB LDAP \
passwordDB LDAP \
ldapServer &#039;ldap://ldap.example.com&#039; \
managerDn &#039;cn=lemonldapng,ou=dsa,dc=example,dc=com&#039; \
managerPassword &#039;changeit&#039; \
ldapBase &#039;ou=users,dc=example,dc=com&#039;
/usr/share/lemonldap-ng/bin/lemonldap-ng-cli -yes 1 \
addKey \
ldapExportedVars uid uid \
ldapExportedVars cn cn \
ldapExportedVars sn sn \
ldapExportedVars mobile mobile \
ldapExportedVars mail mail \
ldapExportedVars givenName givenName
/usr/share/lemonldap-ng/bin/lemonldap-ng-cli -yes 1 \
set \
ldapGroupBase &#039;ou=groups,dc=example,dc=com&#039; \
ldapGroupObjectClass groupOfNames \
ldapGroupAttributeName member \
ldapGroupAttributeNameGroup dn \
ldapGroupAttributeNameSearch cn \
ldapGroupAttributeNameUser dn \
ldapGroupRecursive 1</pre>
</div>
<!-- EDIT6 SECTION "Configure LDAP authentication backend" [5305-6778] -->
<h2 class="sectionedit7" id="configure_saml_identity_provider">Configure SAML Identity Provider</h2>
<div class="level2">
<p>
You can then generate a private key and a self-signed certificate with these commands;
</p>
<pre class="code">openssl req -new -newkey rsa:4096 -keyout saml.key -nodes -out saml.pem -x509 -days 3650</pre>
<p>
Fix the certificate key format (you can skip this step if you are running &gt;= 2.0.6)
</p>
<pre class="code">sed -e &quot;s/END PRIVATE/END RSA PRIVATE/&quot; \
-e &quot;s/BEGIN PRIVATE/BEGIN RSA PRIVATE/&quot; \
-i saml.key</pre>
<p>
Import them in configuration and activate the <abbr title="Security Assertion Markup Language">SAML</abbr> issuer
</p>
<pre class="code">/usr/share/lemonldap-ng/bin/lemonldap-ng-cli -yes 1 \
set \
samlServicePrivateKeySig &quot;`cat saml.key`&quot; \
samlServicePublicKeySig &quot;`cat saml.pem`&quot; \
issuerDBSAMLActivation 1</pre>
<p>
You can also define organization name and <abbr title="Uniform Resource Locator">URL</abbr> for <abbr title="Security Assertion Markup Language">SAML</abbr> metadata:
</p>
<pre class="code">/usr/share/lemonldap-ng/bin/lemonldap-ng-cli -yes 1 \
set \
samlOrganizationName &#039;ACME&#039; \
samlOrganizationDisplayName &#039;ACME Corporation&#039; \
samlOrganizationURL &#039;http://www.acme.com&#039;</pre>
</div>
<!-- EDIT7 SECTION "Configure SAML Identity Provider" [6779-7785] -->
<h2 class="sectionedit8" id="register_an_saml_service_provider">Register an SAML Service Provider</h2>
<div class="level2">
<p>
In this example we have:
</p>
<ul>
<li class="level1"><div class="li"> SP configuration key: testsp</div>
</li>
<li class="level1"><div class="li"> SP metadata file: metadata-testsp.xml</div>
</li>
<li class="level1"><div class="li"> SP exported attribute: EmailAdress (filled with mail session key)</div>
</li>
</ul>
<pre class="code">/usr/share/lemonldap-ng/bin/lemonldap-ng-cli -yes 1 \
addKey \
samlSPMetaDataXML/testsp samlSPMetaDataXML &quot;`cat metadata-testsp.xml`&quot; \
samlSPMetaDataExportedAttributes/testsp mail &#039;1;EmailAddress&#039;</pre>
</div>
<!-- EDIT8 SECTION "Register an SAML Service Provider" [7786-8238] -->
<h2 class="sectionedit9" id="configure_openid_connect_identity_provider">Configure OpenID Connect Identity Provider</h2>
<div class="level2">
<p>
Activate the OpenID Connect Issuer and set issuer name (equal to portal <abbr title="Uniform Resource Locator">URL</abbr>):
</p>
<pre class="code">/usr/share/lemonldap-ng/bin/lemonldap-ng-cli -yes 1 \
set \
issuerDBOpenIDConnectActivation 1 \
oidcServiceMetaDataIssuer http://auth.example.com</pre>
<p>
Generate keys:
</p>
<pre class="code">openssl genrsa -out oidc.key 4096
openssl rsa -pubout -in oidc.key -out oidc_pub.key</pre>
<p>
Import them:
</p>
<pre class="code">/usr/share/lemonldap-ng/bin/lemonldap-ng-cli -yes 1 \
set \
oidcServicePrivateKeySig &quot;`cat oidc.key`&quot; \
oidcServicePublicKeySig &quot;`cat oidc_pub.key`&quot; \
oidcServiceKeyIdSig &quot;`genpasswd`&quot;</pre>
<p>
If needed you can allow implicit and hybrid flows:
</p>
<pre class="code">/usr/share/lemonldap-ng/bin/lemonldap-ng-cli -yes 1 \
set \
oidcServiceAllowImplicitFlow 1 \
oidcServiceAllowHybridFlow 1</pre>
</div>
<!-- EDIT9 SECTION "Configure OpenID Connect Identity Provider" [8239-9122] -->
<h2 class="sectionedit10" id="register_an_openid_connect_relying_party">Register an OpenID Connect Relying Party</h2>
<div class="level2">
<p>
In this example we have:
</p>
<ul>
<li class="level1"><div class="li"> RP configuration key: testrp</div>
</li>
<li class="level1"><div class="li"> Client ID : testclientid</div>
</li>
<li class="level1"><div class="li"> Client secret : testclientsecret</div>
</li>
<li class="level1"><div class="li"> Allowed redirection <abbr title="Uniform Resource Locator">URL</abbr>:</div>
<ul>
<li class="level2"><div class="li"> For login: <a href="https://testrp.example.com/?callback=1" class="urlextern" title="https://testrp.example.com/?callback=1" rel="nofollow">https://testrp.example.com/?callback=1</a></div>
</li>
<li class="level2"><div class="li"> For logout: <a href="https://testrp.example.com/" class="urlextern" title="https://testrp.example.com/" rel="nofollow">https://testrp.example.com/</a></div>
</li>
</ul>
</li>
<li class="level1"><div class="li"> Exported attributes:</div>
<ul>
<li class="level2"><div class="li"> email =&gt; mail</div>
</li>
<li class="level2"><div class="li"> familiy_name =&gt; sn</div>
</li>
<li class="level2"><div class="li"> name =&gt; cn</div>
</li>
</ul>
</li>
</ul>
<ul>
<li class="level1"><div class="li"> Exported attributes:</div>
</li>
</ul>
<pre class="code">/usr/share/lemonldap-ng/bin/lemonldap-ng-cli -yes 1 \
addKey \
oidcRPMetaDataExportedVars/testrp email mail \
oidcRPMetaDataExportedVars/testrp family_name sn \
oidcRPMetaDataExportedVars/testrp name cn</pre>
<ul>
<li class="level1"><div class="li"> Credentials:</div>
</li>
</ul>
<pre class="code">/usr/share/lemonldap-ng/bin/lemonldap-ng-cli -yes 1 \
addKey \
oidcRPMetaDataOptions/testrp oidcRPMetaDataOptionsClientID testclientid \
oidcRPMetaDataOptions/testrp oidcRPMetaDataOptionsClientSecret testclientsecret</pre>
<ul>
<li class="level1"><div class="li"> Redirection:</div>
</li>
</ul>
<pre class="code">/usr/share/lemonldap-ng/bin/lemonldap-ng-cli -yes 1 \
addKey \
oidcRPMetaDataOptions/testrp oidcRPMetaDataOptionsRedirectUris &#039;https://testrp.example.com/?callback=1&#039; \
oidcRPMetaDataOptions/testrp oidcRPMetaDataOptionsPostLogoutRedirectUris &#039;https://testrp.example.com/&#039;</pre>
<ul>
<li class="level1"><div class="li"> Signature and token expiration:</div>
</li>
</ul>
<pre class="code">/usr/share/lemonldap-ng/bin/lemonldap-ng-cli -yes 1 \
addKey \
oidcRPMetaDataOptions/testrp oidcRPMetaDataOptionsIDTokenSignAlg RS512 \
oidcRPMetaDataOptions/testrp oidcRPMetaDataOptionsIDTokenExpiration 3600 \
oidcRPMetaDataOptions/testrp oidcRPMetaDataOptionsAccessTokenExpiration 3600</pre>
</div>
<!-- EDIT10 SECTION "Register an OpenID Connect Relying Party" [9123-10754] -->
<h2 class="sectionedit11" id="categories_and_applications_in_menu">Categories and applications in menu</h2>
<div class="level2">
<p>
Create the category &quot;applications&quot;:
</p>
<pre class="code">/usr/share/lemonldap-ng/bin/lemonldap-ng-cli -yes 1 \
addKey \
applicationList/applications type category \
applicationList/applications catname Applications</pre>
<p>
Create the application &quot;sample&quot; inside category &quot;applications&quot;:
</p>
<pre class="code">/usr/share/lemonldap-ng/bin/lemonldap-ng-cli -yes 1 \
addKey \
applicationList/applications/sample type application \
applicationList/applications/sample/options description &quot;A sample application&quot; \
applicationList/applications/sample/options display &quot;auto&quot; \
applicationList/icons/kmultiple.png&quot; \
applicationList/applications/sample/options name &quot;Sample application&quot; \
applicationList/applications/sample/options uri &quot;https://sample.example.com/&quot;</pre>
</div>
<!-- EDIT11 SECTION "Categories and applications in menu" [10755-11636] -->
<h2 class="sectionedit12" id="encryption_key">Encryption key</h2>
<div class="level2">
<p>
To update the master encryption key:
</p>
<pre class="code">/usr/share/lemonldap-ng/bin/lemonldap-ng-cli -yes 1 \
set \
key &#039;xxxxxxxxxxxxxxx&#039;</pre>
</div>
<!-- EDIT12 SECTION "Encryption key" [11637-] --></div>
</body>
</html>