Módosítások

DrupalShibbolethReadmeDev

9 195 bájt hozzáadva, 2015. január 22., 00:11
Profile module
Drupal '''shib_auth''' module enables [http://shibboleth.internet2.edu Shibboleth] authentication for [http://drupal.org Drupal CMS].
== Installation and bootstrapping =={{STOP|This document is written for module version 4The following documentation assumes that* You [https://wiki.0-x ('''development branch''')shibboleth. Please consult the net/confluence/display/SHIB2/FlowsAndConfig understand how Shibboleth works]* You have [[#Change loghttps://wiki.shibboleth.net/confluence/display/SHIB2/Installation successfully installed and configured Shibboleth SP]] for the revisions of this document for the previous releaseson your host running Drupal.}} == Installation = Installing the module ===
# Download module source for your Drupal version from the [http://drupal.org/project/shib_auth project page].
# Uncompress archive to the <code>modules/</code> directory
# Enable module at '''<code>Administer -> Site building -> Modules</code>'''
==== Compatibility ====Module is being developed for Drupal 6The module assumes that you use Shibboleth SP 2.x. We have stopped backporting new features It's possible to use the 5module with Shibboleth SP 1.x branch and Drupal 7 3, but that version is not yet supported as long as it isn't the stable branchanymore. If you want to contribute to development or porting, please contact '''aai _AT_ niif _DOT_ hu'''!
Both Shibboleth 1.3 and Shibboleth 2.x are supported, although some features might require Shibboleth 2.x.
=== Upgrading the module ===
{{ATTENTION_EN|If you upgrade from 3.x (or previous versions) to 4.x, '''you must update the database'''. After overwriting the files in the <code>modules/</code> directory, open up <code>YOUR_DRUPAL_INSTALLATION/update.php</code> in your browser and run update for the <code>shib_auth</code> module. '''This is required to let your user info persist.'''
}}
The upgrade script creates a new makes slight changes to the database table called <code>shib_authmap</code>, and place the usernames that were registered by the module into it. You only need to run this script once, however running it several times does no harm to your installation apart from showing some SQL errors. :: '''Note:''' {{NOTE_EN|although the upgrade script was designed to be robust, please '''back up your database''' before upgrading.}}==== Moving from Drupal 6 to Drupal 7 ====To migrate your working installation to D7, first you must update your module to the latest 4.x version. After that, you can perform the Drupal update.===Get it running = Configuration ====== Configuring Shibboleth ====You should be familiar with protecting resources with Shibboleth before using this module. (See [https://spaceswiki.internet2shibboleth.edunet/confluence/display/SHIB2/NativeSPProtectContent Shibboleth Wiki]for comprehensive information) Please check that Shibboleth authentication is working for the location of your Drupal installation and all the necessary attributes are exported to the headers. You can enable [[Drupal Shibboleth module#DEBUG mode | DEBUG mode]] to dump the whole '''$_SERVER''' array. If you can see Shibboleth attributes there, you're fine.
In Shibboleth there are two modes for protecting resources:
* '''Lazy Sessions''': session is only initiated if an application redirects user to the SessionInitiator URL. In this module, it is done by clicking the ''"Login with Shibboleth"'' link. Anonymous access is possible as well as using other authentication methods. This is what you want to use for a CMS that contains ''public information''.
:: <small>Detailed description of [[Lazy Session|lazy sessions]] in Hungarian.</small>
* '''"Strict" Sessions''' (normal sessions): users can only access Drupal content if they have a valid Shibboleth session. In this case, no anonymous access can be granted (not even read-only) and you can not use any auxiliary authentication methods.Most of the advanced features don't work with strict sessions. You should not use this unless you want to protect all the information in the CMS from viewing. {{STOPNOTE_EN|If you decide to use lazy after enabling "strict" sessions and , you donwon't want your users to be able to log in login with a password, admin user. [[#Disallowing password changeAdministering Drupal with strict sessions|you have to disable changing passwordsRead on further]]how to give your own user administrator rights.}} ===== Example Shibboleth configuration ====={{NOTE_EN|this example uses lazy sessions. Configuration for Shibboleth 1.3 is quite similar.}}
'''/etc/shibboleth/shibboleth2.xml snippet''':
AuthType Shibboleth
ShibRequireSession Off
# the following single line is only valid for Shib2
ShibUseHeaders On
require shibboleth
</source>
 {{ATTENTION_EN|You '''MUST''' use <code>ShibUseHeaders On</code> if you use Shibboleth2 with '''<code>mod_rewrite</code>'''. <code>mod_rewrite</code> prefixes CGI environment variables with '''<code>REDIRECT_</code>''', so you have to instruct Shibboleth2 to use headers instead. Shibboleth 1.3 always uses headers, therefore the <code>ShibUseHeaders</code> directive is invalid with Shibboleth 1.3.}} ==== DEBUG mode ====If you enable DEBUG mode on the module configuration interface, you can dump the whole '''$_SERVER''' array, '''$_SESSION''' arrays and additionally the '''$user''' object, if the user is logged in. This mode shows you all the available attributes and helps you diagnosing possible Shibboleth attribute problems.
:: <small>Keep in mind that some users might have a specific attribute while others don't.</small>
===== Debug path prefix =====Leave it empty, if you want to display debug information on every page. Enter the string ''<code>user/</code>'' (mind the trailing slash!) for displaying DEBUG messages only on paths below <code>user/*</code>
Adding a prefix is useful, if you want to enable debugging on an online drupal installation without littering all of the pages with the debugging information. You can set it to a non-existent node as well, in this case, the information will be displayed over the built-in 404 page.
==== Setting Shibboleth parameters for the module ========= Handler settings =====If you are using lazy sessions, you have to define the Shibboleth SessionInitiator to which the user should be directed when she clicks on "Login with Shibboleth". The SessionInitiator can be called on a special URL is constituted of the following:* protocol scheme (<code>http://</code> or <code>https://</code>)* host name * Shibboleth handler URL (usually: <code>/which depends on your Shibbolethconfiguration.sso</code>)* 'location' part of the SessionInitiator definition
If your '''/etc/shibboleth/shibboleth2.xml snippet'''is something like this:
<source lang="xml">
<Sessions lifetime="28800" timeout="3600" checkAddress="false"
<SessionInitiator type="Shib1" defaultACSIndex="5"/>
</SessionInitiator>
<!-- other things -->
<LogoutInitiator type="Chaining" Location="/Logout" relayState="cookie">
<LogoutInitiator type="SAML2" template="bindingTemplate.html"/>
<LogoutInitiator type="Local"/>
</LogoutInitiator>
<!-- other things -->
</Sessions>
</source>
For this example, you should configure the Shibboleth settings of the module as the following:Then your * '''Login URL''' is: <code>http(s?)://your_fully_qualified_domain_name/Shibboleth.sso/Login</code>* ''' for Logout URL''Handler URL''is: <code>http(s?)://your_fully_qualified_domain_name/Shibboleth.sso/Logout</code>{{NOTE_EN| Most common errors are (please check Shibboleth documentation)::::* using ''http'HTTPS'when your Shibboleth SP is configured for '' or https''only (either by Apache settings or the'HTTP'handlerSSL'' parameter):::* you want to use another SessionInitiator (for ''scheme''example with Discovery Service), depending on whether you are using SSL or notsuch as <code>/DS</code>* '''/Login''' for ''WAYF location''}}
===== Attribute settings =====
Specify here the '''$_SERVER''' headers to look up the user's username and e-mail address. Please check '''DEBUG''' mode to look for the available headers. If you can not find the desired attribute, then something is wrong with your IdP-SP attribute release flow.
Both fields can have the same value, if you wish.
===== Redirecting authenticated users to HTTPS =====It's a common problem if Shibboleth SP is configured on HTTPS only (<code>handlerSSL="true"</code>), while the site also works on plain HTTP. By using ''Force HTTPS on login'' feature, you can redirect your users to HTTPS at login time. This way you can have your anonymous users view your site unencrypted (which saves some CPU cycles), but once they login, they get redirected to HTTPS (which is the only secure use of Shibboleth SP). {{NOTE_EN|If you don't see Shibboleth attributes in DEBUG although you have double checked that you have set <code>AuthType shibboleth</code>, <code>require shibboleth</code> in your <code>.htaccess</code> file, you most probably need to turn this feature on.}} == Understanding features ===== Automatic user creation ===Drupal CMS requires all users to be in its internal SQL database. If the module detects that no user exists in the database with the received Shibboleth user identifier, it creates a new (Drupal) user.  Drupal needs 3 pieces of information to create a new user:* username* e-mail address* password The module by default uses the username and e-mail address taken from the <code>$_SERVER</code> headers, see [[#Attribute settings]] right above. On new user creation a random password is generated. This can be overwritten by the user unless you [[#Disallowing password change|disallow it]] by the userprotect module.{{NOTE_EN|if the user overwrites the password, she can log in with her username and the new password.}}==== Using custom values =====
You may want to let your users to define their own Drupal usernames and e-mail addresses other than what was received from the IdP. If either ''User-defined usernames'' or ''User-defined e-mail addresses'' option is set, new users are presented a form to enter data at the first logon.
{{INFO_EN|
* The module ensures that neither values are in use by existing users.
* If you enable and later disable the options, the two behave a bit differently. On subsequent logons:
** the user-defined username is '''preserved'''
** e-mail address gets '''rewritten''' (or the user gets a fatal error if the IdP does not provide the data)
* User-defined e-mail addresses are not verified, only well-formedness is checked
}}
==== Working with federated identifiers ====
If you enable the option ''User-defined usernames'' in the module configuration, every new user is presented a form to specify a Drupal username. This way you can work with opaque (federated) identifiers such as <code>eduPersonTargetedId</code>, as long as it appears in the $_SERVER variable holding the username. The only limitation is that the federated identifier cannot be longer than 255 characters, however it can contain characters otherwise not allowed in Drupal account names (such as exclamation mark, etc).
==== Disallowing password change ====
If you don't want to let your users to change passwords and log in with it, you may want to disallow password change.
# Install Drupal [http://drupal.org/project/userprotect User Protect module]
# At Administer -> User management -> User Protect -> Protected roles tab check '''password''' for the ''authenticated user'' role.
# At Administer -> Permissions -> userprotect module: uncheck '''change own password''' for ''authenticated user''
# Log in with a normal account, go to "My account" -> Edit. You shouldn't see the possibility for changing password; except for the case when the user has user administrator rights.
==== Administering Drupal with strict sessions ====
If you use strict sessions, you can not log in with a password. You need to grant your own user administrator rights to administer the CMS.
# Enable Shibboleth protection
# Login with your own user credentials, so that your Drupal user profile is created
# Disable Shibboleth protection
# Login as 'admin', grant your own user 'Administrator' rights.
# Enable Shibboleth protection
# Login with your own credentials, you should have 'Administrator' rights now.
==== Pre-creating users ====
Versions before 4.0 allowed pre-creating users without any tweaks; if the username matched, the user was logged in.
=== Logging out ======= Session expiry ====Enable Since 4.0 the module only logs in users who exist in <code>{shib_authmap}</code> and the option "update script only takes care of users tagged with 'shib_auth'Destroy Drupal session when in <code>{authmap}</code>. When there is no mapping in the Shibboleth session expires''"<code>{shib_authmap}</code>, if you want a new user is attempted to force logout be created, which fails because of the mail being duplicated. So what was accidentally working with pre-created users without a valid Shibboleth session, do not work anymore with 4.0.  To pre-create users, you should first create the Drupal users in your preferred way (This only applies to lazy sessionseither by using the administration interface or by direct SQL query), otherwise and then you are always having a Shibboleth session.) '''MUST''' manually run the following '''three queries''':
{{INFO_EN|;Keep in mind if you leave this option off:<source lang="SQL">* if the Shibboleth session is lostINSERT INTO shib_authmap (uid, all the Shibboleth-derived attributes disappeartargeted_id) SELECT uid, therefore the user loses the [[#Dynamic role assignment|assigned Shibboleth roles]]name FROM users WHERE uid > 1 AND (uid) NOT IN** on the other hand, the roles assigned to the ''Drupal account of the user'' persist as long as the Drupal session is valid (SELECT uid* Shibboleth session might get lost if you use a clustered SP without a central session cache}} FROM shib_authmap);
==== URL to redirect to after logout ====INSERT INTO authmap (uid, authname)Define an URL here SELECT uid, where you want the user to be navigated after logout. The URL can be absolute or relative to the server base url. The relative paths will be automatically extended with the site base URL.targeted_id FROM shib_authmap WHERE (uid) NOT IN (SELECT uid FROM authmap);
UPDATE authmap SET module ==== SAML2 Logout ===='shib_auth'At the moment, Shibboleth2 SP supports SAML2 logout while the Shibboleth2 IdP does not. It has a consequence that WHERE (if you have a standard Shibboleth2 installationuid), you will get a Shibboleth error message on logout, like this:IN Global Logout (SELECT uid Status of Global Logout: Identity provider does not support SAML 2 Single Logout protocol.You can avoid this message by commenting out SAML2 global logout initiator from <code>/Logout</code> handler in <code>/etc/shibboleth/shibboleth2.xml</code>:<source lang="xml"> <!-- LogoutInitiators enable SP-initiated local or global/single logout of sessions. --> <LogoutInitiator type="Chaining" Location="/Logout" relayState="cookie"> <!-- The following line should be commented out to make Drupal logout work, as long as your IdPs do not support SAML2 logout --> <!--LogoutInitiator type="SAML2" template="bindingTemplate.html"/--> <LogoutInitiator type="Local"/> </LogoutInitiator> FROM shib_authmap);
</source>
 {{NOTE_EN|These queries add all your existing users to <code>shib_authmap</code> with their usernames and make sure that your <code>authmap</code> table contains all of the user entries. You should optimize these queries if you have a large number of users.}} {{ATTENTION_EN|You should repeat these queries each time after you add pre-created users.}} === Dynamic role Role assignment ===
It's possible to assign roles to users based on their Shibboleth attributes.
* '''$_SERVER''' header name: name of the Shibboleth-derived attribute
* '''Value regexp''': regexp applied to (all) the value(s) of the Shibboleth-derived attribute
* '''Role(s)''': checklist of roles to be assigned for to the matching users
All these ==== Dynamic rules are evaluated at module initiation time(default) ====Dynamic rules add roles to the user, but '''do not save them to the user's profile'''. That This means that revoking* the roles assigned by dynamic rules are '''NOT displayed on the user page''', even though the permissions assigned to the role are in effect* the roles assigned by dynamic rules are '''automatically revoked''' if the Shibboleth attributes change (ie. <code>eduPersonAffiliation</adding a code> changes from <code>student</code> to <code>alum</code>),* thus if the user logs in by other means than Shibboleth attribute , the rule will take effect immediately on next page refresh. The same applies when not be triggered, so the set of headers is happened to roles will not be changedassigned.
{{NOTE_EN|Although dynamic Additional roles are can be assigned statically to the user (as an individual) by the administrator as normally. Every logged in user gets the role <code>Authenticated user</code> automatically.==== Sticky rules ====On the other hand, sticky rules do '''save the roles to the user'NOTs profile''' . Thus* the roles assigned by sticky rules are displayed on the user page, * the permissions assigned to roles are not revoked automatically by the module,* the role are roles will be in effect for regardless of the userlogin procedure. <br><small>This is a feature, not a bug</small>}}
Additional roles can be assigned statically to === User profile mapping ===From the user 7.x-4.2 version (as an individualD6 is not supported) by it is possible to define a mapping between Shibboleth attributes and Drupal Fields. You must have the ''Field UI'' and the ''Shibboleth profile fields'' modules enabled to use this functionality. Unlike other features of the module, this mapping is configured together with the administrator as normallyfield definition.
== Using module ===== Automatic user creation ===Drupal CMS requires all users Go to ''Administration » Configuration » People » Account settings » Manage fields'' (<code>admin/config/people/accounts/fields</code>) and create a new field or edit an existing one. The Shibboleth mapping is available on the Field Edit form and can be used in its internal SQL database. If the module detects that three ways:* ''Disabled'': no user exists in mapping (this is the database with the received default);* ''Initial value from Shibboleth user identifier, it creates a new (Drupal) user. === Disallowing password change ===There later editable by User'': the value of the mapping is no way for only assigned to the module to detect field if a user the field has been deleted from no values;* ''Always update value on User login, not editable by User'': the IdP. This simple fact has a number of consequencesfield is updated on every login.
When a user is first logged You can use the values of the server variables by referring to them with square brackets like <code>[sn]</code>. You can reference multiple server variables in, a Drupal account one mapping. Anything that is automatically created for her. Because Drupal requires not matched to a password, a random server variable will be treated as string and copied to the value of the field. The server variable match is generated for password. Normally the user doesn't need to know itcase insensitive.
Now suppose that your user is about to leave your institution. If she is malicious enoughAs an example, she can go to consider the password change form, reset her password to a known one, and even after she is deleted from the IdP, she still can log in to your precious resource with user's request containing the following server variables (now known) password. (Note that it is only achievable with lazy sessions!regardless of being set by Shibboleth or by something else): [givenName] -> John [sn] -> Doe [email] -> jdoe@example.com
Therefore, if your requirements are such that only Shibboleth-authenticated users can log in, '''you have to disable changing passwords''' for users. The following mappings would produce the results as indicated:{|;Steps for disallowing your users to change their passwords:# Install Drupal |<code>[sn], [givenName] <[http://drupal.org/project/userprotect User Protect moduleemail]# At Administer -> User management -> User Protect -</code> Protected roles tab check || '''password''Doe, John <jdoe@example.com>' for the ''authenticated user'' role.||# At Administer |-|<code> Permissions -[firstName] [sn]</code> userprotect module: uncheck || '''change own password''[firstname] Doe' for ''authenticated user''(note the mistaken header name)# Log in with a normal account, go to "My account" -> Edit. You shouldn't see the possibility for changing password; except for the case when the user has user administrator rights.|}
=== Account linking ===
On the other hand, there There might be cases when you have a number of existing users and you want them to (optionally) log in through the federation. If you enable '''account linking''', a user can add her SSO login to her existing Drupal account. The process of adding an SSO login -> Drupal account association is the following (all steps are performed by the user):
# Login to Drupal (with username/password)
# Go to <code>My account -> Edit</code>
* If the administrator disables this feature, no new associations can be stored. Existing associations remain in effect.
* On a new user logon, the one cannot choose the Drupal username of another user (when ''user-defined usernames'' is active). For account linking, the user must be already logged in.
* Currently account linking link is not displayed if the user has been logged in using Shibboleth. If you want to support users with multiple federated identities, please file a feature request.
}}
{{UNCERTAINATTENTION_EN|* Account linking is disabled when the user is logged in by the module. This might change in the future. * Dynamic roles are roles assigned to based on server variables, not users. These may well be different on username/password logon and Shibboleth logon.
}}
=== Working with federated identifiers ===
If you enable the option ''User-defined usernames'' in the module configuration, every new user is presented a form to specify a Drupal username. This way you can work with opaque (federated) identifiers such as <code>eduPersonTargetedId</code>, as long as it appears in the $_SERVER variable holding the username. The only limitation is that the federated identifier cannot be longer than 255 characters, however it can contain characters otherwise not allowed in Drupal account names (such as exclamation mark, etc).
=== Administrator / password login Logging out ======= Session expiry ====If Enable the option "''Destroy Drupal session when the Shibboleth session expires''", if you are using want to force logout the users without a valid Shibboleth session. (This only applies to lazy sessions, otherwise it is the webserver what ensures that you can still login with passwordhave a valid session. If ) {{INFO_EN|;Keep in mind if you disabled leave this option off:* if the username/password login blockShibboleth session is lost, [[#Dynamic role assignment|assigned dynamic roles]] are lost, append too* Shibboleth session might get lost if you use a clustered SP without a central session cache* '''Never ever leave this option off if you want support Single Logout'''. Otherwise the following user will remain logged in to your normal Drupal even after doing single (global) logout.}} ==== URL to redirect to after logout ====Define an URL here, where you want the user to be navigated after logout. The URLcan be absolute or relative to the server base url. The relative paths will be automatically extended with the site base URL. ==== SAML2 Logout ====At the moment, Shibboleth2 SP supports SAML2 logout while the Shibboleth2 IdP does not. It has a consequence that (if you have a standard Shibboleth2 installation), you will get a Shibboleth error message on logout, like this: Global Logout Status of Global Logout: Identity provider does not support SAML 2 Single Logout protocol.You can avoid this message by commenting out SAML2 global logout initiator from <code>/?q=userLogout</code> handler in <code>/etc/shibboleth/shibboleth2.xml</code>:<source lang="xml"> <!-- LogoutInitiators enable SP-initiated local or global/single logout of sessions. --> <LogoutInitiator type="Chaining" Location="/Logout" relayState= Administering "cookie"> <!-- The following line should be commented out to make Drupal with strict sessions logout work, as long as your IdPs do not support SAML2 logout --> <!--LogoutInitiator type="SAML2" template="bindingTemplate.html"/--> <LogoutInitiator type="Local"/> </LogoutInitiator></source> ===User consent ===In certain scenarios you are only allowed to store personal data if the user accepted some kind of legal agreement such as the Terms of Use or the Privacy Policy.  When a new user arrives, she gets a screen with a link to the legal document and a checkbox. This page also contains the user's name and the e-mail address. Personal data required for login are stored only if the user accepts the agreement. If it's allowed by the administrator, the user might set [[#Using_custom_values | custom values]] for those attributes.  If you use strict sessionsthe document changes, you can not log the administrator might increment the version. This case all users are forced to accept the new version of the agreement before logging in .{{NOTE_EN|Version matching is an exact match, so the user must accept exactly the same version what was specified by the administrator}}==== Personal data handled by the module ====* username* user's e-mail address* user's targeted identifier(s) (what is sent by the IdP, if different from username), along with a mapping to the Drupal username* Identity Provider(s) that identified the user* random password(this might not be considered personal data)* time of the registration === Advanced SAML2 features ===SAML2 defines several properties of the authentication request message which may affect the authentication performed by the IdP.{{STOP|'''Be careful when using these options. It's quite tricky ''  IdPs that do not support these features might signal an error instead of performing any kind of authentication of the user. Or might show errors ''after'' authenticating the user. Some kind of authentication handlers (ie. HTTP Basic Auth) will never work even if the IdP software is capable of handling these properties. }}==== isPassive ====If <code>isPassive</code> is set, then the user is redirected to the IdP or to the Discovery Service in advance, but neither of them are allowed to take over the control of the user interface (such as performing any visible authentication). If authentication (or IdP selection) can not be performed silently, an error is returned, which is then handled by the module.  By using this option, you can auto-login users who are already logged in to the IdP even if you are using lazy sessions. If auto-login can not be performed, the user returns to Drupal unauthenticated without seeing any error message. {{ATTENTION_EN|You need to instruct Shibboleth to redirect errors back to Drupal to circumvent ithandle passive authentication failures. This is done by setting <code>redirectErrors</code> parameter in the RequestMap. See [https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPContentSettings Shibboleth wiki] for details.# Enable Shibboleth protection# Login with your own user credentials'''IMPORTANT''': current implementation does not handle any errors except for NoPassive error. This means, so that your on every possible Shibboleth SP error you will get an unauthenticated Drupal page instead of a Shibboleth error page.}}{{NOTE_EN|this feature requires JavaScript.}}==== forceAuthn ====This feature requires reauthentication of the user profile at the IdP even if she is createdhaving an SSO session there. Just like isPassive, it's not generally supported by authentication handlers.# Disable Shibboleth protection# Login as In general, you should never mix '''isPassive''' and '''forceAuthn''admin'. The standard states that in this case, grant your own the IdP must reauthenticate the user without visibly taking control of the user interface. It'Administrator' rightss up to you, how you interpret it...# Enable Shibboleth protection==== Non-implemented features ====# Login with your own credentialsThere are several other SAML features which are not yet implemented, because there seems to be very little practical interest for them. Please file a feature request if you really need them, but before doing so, please, spend a little time on thinking how things should have really work.* '''AuthnContextClass''': the SP can request some specific authentication context from the IdP.* '''NameID management''': the IdP can request to change the user's NameID (targeted identifier) or to remove it.* '''Logout notification''Administrator' rights now: this is a Shibboleth2 feature, not a SAML one. You generally do not need this, because you can terminate the Drupal session on Shibboleth session expiry. This workaround has the disadvantage that the module will not be notified at the time when the user was logged out, only on the next page refresh.
== Change log ==
; Bug fixes
* The module now works with caching enabled
* Code refactoring
; New features
* Allow specifying Drupal username, thus support opaque identifiers
* Support for sticky rules (roles saved permanently to the users' profile)* Basic support for account linking* Basic support for getting user consent on personal data* Support for isPassive and forceAuthn session initiation* Support for redirecting users to HTTPS on login
[[Category: AAI]] [[Category: Drupal]] [[Category: Shibboleth SP]] [[Category: HOWTO]] [[Category: English]]

Navigációs menü